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/rpc/dcerpc_util.h"
28 #include "librpc/gen_ndr/auth.h"
29 #include "auth/gensec/gensec.h"
30 #include "lib/util/dlinklist.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/tsocket/tsocket.h"
34 #include "librpc/gen_ndr/ndr_dcerpc.h"
35 #include "lib/util/tevent_ntstatus.h"
39 #define DBGC_CLASS DBGC_RPC_SRV
41 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
42 const struct dcerpc_bind *b,
43 struct dcerpc_ack_ctx *ack_ctx_list);
46 see if two endpoints match
48 static bool endpoints_match(const struct dcerpc_binding *ep1,
49 const struct dcerpc_binding *ep2)
51 enum dcerpc_transport_t t1;
52 enum dcerpc_transport_t t2;
56 t1 = dcerpc_binding_get_transport(ep1);
57 t2 = dcerpc_binding_get_transport(ep2);
59 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
60 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
70 if (strcasecmp(e1, e2) != 0) {
78 find an endpoint in the dcesrv_context
80 _PUBLIC_ NTSTATUS dcesrv_find_endpoint(struct dcesrv_context *dce_ctx,
81 const struct dcerpc_binding *ep_description,
82 struct dcesrv_endpoint **_out)
84 struct dcesrv_endpoint *ep = NULL;
85 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
86 if (endpoints_match(ep->ep_description, ep_description)) {
91 return NT_STATUS_NOT_FOUND;
95 find a registered context_id from a bind or alter_context
97 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
100 struct dcesrv_connection_context *c;
101 for (c=conn->contexts;c;c=c->next) {
102 if (c->context_id == context_id) return c;
108 see if a uuid and if_version match to an interface
110 static bool interface_match(const struct dcesrv_interface *if1,
111 const struct dcesrv_interface *if2)
113 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
114 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
118 find the interface operations on any endpoint with this binding
120 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
121 struct dcerpc_binding *binding,
122 const struct dcesrv_interface *iface)
124 struct dcesrv_endpoint *ep;
125 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
126 if (endpoints_match(ep->ep_description, binding)) {
127 struct dcesrv_if_list *ifl;
128 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
129 if (interface_match(ifl->iface, iface)) {
139 see if a uuid and if_version match to an interface
141 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
142 const struct GUID *uuid, uint32_t if_version)
144 return (iface->syntax_id.if_version == if_version &&
145 GUID_equal(&iface->syntax_id.uuid, uuid));
149 find the interface operations on an endpoint by uuid
151 _PUBLIC_ const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
152 const struct GUID *uuid, uint32_t if_version)
154 struct dcesrv_if_list *ifl;
155 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
156 if (interface_match_by_uuid(ifl->iface, uuid, if_version)) {
164 find the earlier parts of a fragmented call awaiting reassembily
166 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
168 struct dcesrv_call_state *c;
169 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
170 if (c->pkt.call_id == call_id) {
178 register an interface on an endpoint
180 An endpoint is one unix domain socket (for ncalrpc), one TCP port
181 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
183 Each endpoint can have many interfaces such as netlogon, lsa or
184 samr. Some have essentially the full set.
186 This is driven from the set of interfaces listed in each IDL file
187 via the PIDL generated *__op_init_server() functions.
189 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
191 const char *ncacn_np_secondary_endpoint,
192 const struct dcesrv_interface *iface,
193 const struct security_descriptor *sd)
195 struct dcesrv_endpoint *ep;
196 struct dcesrv_if_list *ifl;
197 struct dcerpc_binding *binding;
198 struct dcerpc_binding *binding2 = NULL;
201 enum dcerpc_transport_t transport;
202 char *ep_string = NULL;
203 bool use_single_process = true;
204 const char *ep_process_string;
207 * If we are not using handles, there is no need for force
208 * this service into using a single process.
210 * However, due to the way we listen for RPC packets, we can
211 * only do this if we have a single service per pipe or TCP
212 * port, so we still force a single combined process for
215 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
216 use_single_process = false;
219 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
221 if (NT_STATUS_IS_ERR(status)) {
222 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
226 transport = dcerpc_binding_get_transport(binding);
227 if (transport == NCACN_IP_TCP) {
232 * First check if there is already a port specified, eg
233 * for epmapper on ncacn_ip_tcp:[135]
236 = dcerpc_binding_get_string_option(binding,
238 if (endpoint == NULL) {
239 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
240 "rpc server port", iface->name, 0);
243 * For RPC services that are not set to use a single
244 * process, we do not default to using the 'rpc server
245 * port' because that would cause a double-bind on
248 if (port == 0 && !use_single_process) {
249 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
252 snprintf(port_str, sizeof(port_str), "%u", port);
253 status = dcerpc_binding_set_string_option(binding,
256 if (!NT_STATUS_IS_OK(status)) {
263 if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) {
264 enum dcerpc_transport_t transport2;
266 status = dcerpc_parse_binding(dce_ctx,
267 ncacn_np_secondary_endpoint,
269 if (!NT_STATUS_IS_OK(status)) {
270 DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n",
271 ncacn_np_secondary_endpoint));
275 transport2 = dcerpc_binding_get_transport(binding2);
276 SMB_ASSERT(transport2 == transport);
279 /* see if the interface is already registered on the endpoint */
280 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
281 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
282 iface->name, ep_name));
283 return NT_STATUS_OBJECT_NAME_COLLISION;
286 /* check if this endpoint exists
288 status = dcesrv_find_endpoint(dce_ctx, binding, &ep);
289 if (NT_STATUS_IS_OK(status)) {
291 * We want a new port on ncacn_ip_tcp for NETLOGON, so
292 * it can be multi-process. Other processes can also
293 * listen on distinct ports, if they have one forced
294 * in the code above with eg 'rpc server port:drsuapi = 1027'
296 * If we have mulitiple endpoints on port 0, they each
297 * get an epemeral port (currently by walking up from
300 * Because one endpoint can only have one process
301 * model, we add a new IP_TCP endpoint for each model.
303 * This works in conjunction with the forced overwrite
304 * of ep->use_single_process below.
306 if (ep->use_single_process != use_single_process
307 && transport == NCACN_IP_TCP) {
312 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || add_ep) {
313 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
315 return NT_STATUS_NO_MEMORY;
318 ep->ep_description = talloc_move(ep, &binding);
319 ep->ep_2nd_description = talloc_move(ep, &binding2);
322 /* add mgmt interface */
323 ifl = talloc_zero(ep, struct dcesrv_if_list);
325 return NT_STATUS_NO_MEMORY;
328 ifl->iface = talloc_memdup(ifl,
329 dcesrv_get_mgmt_interface(),
330 sizeof(struct dcesrv_interface));
331 if (ifl->iface == NULL) {
333 return NT_STATUS_NO_MEMORY;
336 DLIST_ADD(ep->interface_list, ifl);
337 } else if (!NT_STATUS_IS_OK(status)) {
338 DBG_NOTICE("Failed to find endpoint: %s\n", nt_errstr(status));
343 * By default don't force into a single process, but if any
344 * interface on this endpoint on this service uses handles
345 * (most do), then we must force into single process mode
347 * By overwriting this each time a new interface is added to
348 * this endpoint, we end up with the most restrictive setting.
350 if (use_single_process) {
351 ep->use_single_process = true;
354 /* talloc a new interface list element */
355 ifl = talloc_zero(ep, struct dcesrv_if_list);
357 return NT_STATUS_NO_MEMORY;
360 /* copy the given interface struct to the one on the endpoints interface list */
361 ifl->iface = talloc_memdup(ifl,
363 sizeof(struct dcesrv_interface));
364 if (ifl->iface == NULL) {
366 return NT_STATUS_NO_MEMORY;
369 /* if we have a security descriptor given,
370 * we should see if we can set it up on the endpoint
373 /* if there's currently no security descriptor given on the endpoint
376 if (ep->sd == NULL) {
377 ep->sd = security_descriptor_copy(ep, sd);
380 /* if now there's no security descriptor given on the endpoint
381 * something goes wrong, either we failed to copy the security descriptor
382 * or there was already one on the endpoint
384 if (ep->sd != NULL) {
385 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
386 " on endpoint '%s'\n",
387 iface->name, ep_name));
388 if (add_ep) free(ep);
390 return NT_STATUS_OBJECT_NAME_COLLISION;
394 /* finally add the interface on the endpoint */
395 DLIST_ADD(ep->interface_list, ifl);
397 /* if it's a new endpoint add it to the dcesrv_context */
399 DLIST_ADD(dce_ctx->endpoint_list, ep);
402 /* Re-get the string as we may have set a port */
403 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
405 if (use_single_process) {
406 ep_process_string = "single process required";
408 ep_process_string = "multi process compatible";
411 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
412 iface->name, ep_string, ep_process_string);
413 TALLOC_FREE(ep_string);
418 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
419 DATA_BLOB *session_key)
421 if (auth->session_info == NULL) {
422 return NT_STATUS_NO_USER_SESSION_KEY;
425 if (auth->session_info->session_key.length == 0) {
426 return NT_STATUS_NO_USER_SESSION_KEY;
429 *session_key = auth->session_info->session_key;
433 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
434 DATA_BLOB *session_key)
436 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
437 return NT_STATUS_NO_USER_SESSION_KEY;
440 return dcesrv_session_info_session_key(auth, session_key);
443 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
444 DATA_BLOB *session_key)
446 return dcerpc_generic_session_key(session_key);
450 * Fetch the authentication session key if available.
452 * This is the key generated by a gensec authentication.
455 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
456 DATA_BLOB *session_key)
458 struct dcesrv_auth *auth = call->auth_state;
459 SMB_ASSERT(auth->auth_finished);
460 return dcesrv_session_info_session_key(auth, session_key);
464 * Fetch the transport session key if available.
465 * Typically this is the SMB session key
466 * or a fixed key for local transports.
468 * The key is always truncated to 16 bytes.
470 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
471 DATA_BLOB *session_key)
473 struct dcesrv_auth *auth = call->auth_state;
476 SMB_ASSERT(auth->auth_finished);
478 if (auth->session_key_fn == NULL) {
479 return NT_STATUS_NO_USER_SESSION_KEY;
482 status = auth->session_key_fn(auth, session_key);
483 if (!NT_STATUS_IS_OK(status)) {
487 session_key->length = MIN(session_key->length, 16);
492 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
494 const struct dcesrv_endpoint *ep = conn->endpoint;
495 enum dcerpc_transport_t transport =
496 dcerpc_binding_get_transport(ep->ep_description);
497 struct dcesrv_auth *auth = NULL;
499 auth = talloc_zero(conn, struct dcesrv_auth);
506 auth->session_key_fn = dcesrv_remote_session_key;
509 case NCACN_UNIX_STREAM:
510 auth->session_key_fn = dcesrv_local_fixed_session_key;
514 * All other's get a NULL pointer, which
515 * results in NT_STATUS_NO_USER_SESSION_KEY
524 connect to a dcerpc endpoint
526 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
528 const struct dcesrv_endpoint *ep,
529 struct auth_session_info *session_info,
530 struct tevent_context *event_ctx,
531 uint32_t state_flags,
532 struct dcesrv_connection **_p)
534 struct dcesrv_auth *auth = NULL;
535 struct dcesrv_connection *p;
538 return NT_STATUS_ACCESS_DENIED;
541 p = talloc_zero(mem_ctx, struct dcesrv_connection);
542 NT_STATUS_HAVE_NO_MEMORY(p);
544 p->dce_ctx = dce_ctx;
546 p->packet_log_dir = lpcfg_parm_string(dce_ctx->lp_ctx,
550 p->event_ctx = event_ctx;
551 p->state_flags = state_flags;
552 p->allow_bind = true;
553 p->max_recv_frag = 5840;
554 p->max_xmit_frag = 5840;
555 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
557 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
562 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
568 auth = dcesrv_auth_create(p);
571 return NT_STATUS_NO_MEMORY;
574 auth->session_info = talloc_reference(auth, session_info);
575 if (auth->session_info == NULL) {
577 return NT_STATUS_NO_MEMORY;
580 p->default_auth_state = auth;
583 * For now we only support NDR32.
585 p->preferred_transfer = &ndr_transfer_syntax_ndr;
592 move a call from an existing linked list to the specified list. This
593 prevents bugs where we forget to remove the call from a previous
596 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
597 enum dcesrv_call_list list)
599 switch (call->list) {
600 case DCESRV_LIST_NONE:
602 case DCESRV_LIST_CALL_LIST:
603 DLIST_REMOVE(call->conn->call_list, call);
605 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
606 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
608 case DCESRV_LIST_PENDING_CALL_LIST:
609 DLIST_REMOVE(call->conn->pending_call_list, call);
614 case DCESRV_LIST_NONE:
616 case DCESRV_LIST_CALL_LIST:
617 DLIST_ADD_END(call->conn->call_list, call);
619 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
620 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
622 case DCESRV_LIST_PENDING_CALL_LIST:
623 DLIST_ADD_END(call->conn->pending_call_list, call);
628 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
631 struct dcesrv_auth *a = NULL;
633 if (call->conn->terminate != NULL) {
637 call->conn->allow_bind = false;
638 call->conn->allow_alter = false;
640 call->conn->default_auth_state->auth_invalid = true;
642 for (a = call->conn->auth_states; a != NULL; a = a->next) {
643 a->auth_invalid = true;
646 call->terminate_reason = talloc_strdup(call, reason);
647 if (call->terminate_reason == NULL) {
648 call->terminate_reason = __location__;
653 return a dcerpc bind_nak
655 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
657 struct ncacn_packet pkt;
658 struct dcerpc_bind_nak_version version;
659 struct data_blob_list_item *rep;
661 static const uint8_t _pad[3] = { 0, };
664 * We add the call to the pending_call_list
665 * in order to defer the termination.
667 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
669 /* setup a bind_nak */
670 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
672 pkt.call_id = call->pkt.call_id;
673 pkt.ptype = DCERPC_PKT_BIND_NAK;
674 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
675 pkt.u.bind_nak.reject_reason = reason;
676 version.rpc_vers = 5;
677 version.rpc_vers_minor = 0;
678 pkt.u.bind_nak.num_versions = 1;
679 pkt.u.bind_nak.versions = &version;
680 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
682 rep = talloc_zero(call, struct data_blob_list_item);
684 return NT_STATUS_NO_MEMORY;
687 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
688 if (!NT_STATUS_IS_OK(status)) {
692 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
694 DLIST_ADD_END(call->replies, rep);
695 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
697 if (call->conn->call_list && call->conn->call_list->replies) {
698 if (call->conn->transport.report_output_data) {
699 call->conn->transport.report_output_data(call->conn);
706 static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
710 const char *location)
712 const char *reason = NULL;
714 reason = talloc_asprintf(call, "%s:%s: fault=%u (%s) flags=0x%x",
717 dcerpc_errstr(call, fault_code),
719 if (reason == NULL) {
724 * We add the call to the pending_call_list
725 * in order to defer the termination.
728 dcesrv_call_disconnect_after(call, reason);
730 return dcesrv_fault_with_flags(call, fault_code, extra_flags);
733 #define dcesrv_fault_disconnect(call, fault_code) \
734 _dcesrv_fault_disconnect_flags(call, fault_code, \
735 DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
736 __func__, __location__)
738 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
740 DLIST_REMOVE(c->conn->contexts, c);
742 if (c->iface && c->iface->unbind) {
743 c->iface->unbind(c, c->iface);
750 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
752 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
753 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
754 enum dcerpc_transport_t transport =
755 dcerpc_binding_get_transport(endpoint->ep_description);
756 struct dcesrv_connection_context *context = dce_call->context;
757 const struct dcesrv_interface *iface = context->iface;
759 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
761 if (transport == NCALRPC) {
762 context->allow_connect = true;
767 * allow overwrite per interface
768 * allow dcerpc auth level connect:<interface>
770 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
771 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
772 "allow dcerpc auth level connect",
774 context->allow_connect);
777 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
778 const struct dcesrv_interface *iface)
781 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
782 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
784 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
788 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
789 const struct dcesrv_interface *iface)
791 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
795 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
796 const struct dcesrv_interface *iface)
798 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
799 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
800 enum dcerpc_transport_t transport =
801 dcerpc_binding_get_transport(endpoint->ep_description);
803 if (transport == NCALRPC) {
804 context->allow_connect = true;
809 * allow overwrite per interface
810 * allow dcerpc auth level connect:<interface>
812 context->allow_connect = false;
813 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
814 "allow dcerpc auth level connect",
816 context->allow_connect);
820 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
821 const struct dcesrv_interface *iface)
823 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
824 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
825 enum dcerpc_transport_t transport =
826 dcerpc_binding_get_transport(endpoint->ep_description);
828 if (transport == NCALRPC) {
829 context->allow_connect = true;
834 * allow overwrite per interface
835 * allow dcerpc auth level connect:<interface>
837 context->allow_connect = true;
838 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
839 "allow dcerpc auth level connect",
841 context->allow_connect);
845 struct dcesrv_conn_auth_wait_context {
846 struct tevent_req *req;
851 struct dcesrv_conn_auth_wait_state {
855 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
856 struct tevent_context *ev,
859 struct dcesrv_conn_auth_wait_context *auth_wait =
860 talloc_get_type_abort(private_data,
861 struct dcesrv_conn_auth_wait_context);
862 struct tevent_req *req = NULL;
863 struct dcesrv_conn_auth_wait_state *state = NULL;
865 req = tevent_req_create(mem_ctx, &state,
866 struct dcesrv_conn_auth_wait_state);
870 auth_wait->req = req;
872 tevent_req_defer_callback(req, ev);
874 if (!auth_wait->done) {
878 if (tevent_req_nterror(req, auth_wait->status)) {
879 return tevent_req_post(req, ev);
882 tevent_req_done(req);
883 return tevent_req_post(req, ev);
886 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
888 return tevent_req_simple_recv_ntstatus(req);
891 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
893 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
895 if (conn->wait_send != NULL) {
896 return NT_STATUS_INTERNAL_ERROR;
899 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
900 if (auth_wait == NULL) {
901 return NT_STATUS_NO_MEMORY;
904 conn->wait_private = auth_wait;
905 conn->wait_send = dcesrv_conn_auth_wait_send;
906 conn->wait_recv = dcesrv_conn_auth_wait_recv;
910 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
913 struct dcesrv_conn_auth_wait_context *auth_wait =
914 talloc_get_type_abort(conn->wait_private,
915 struct dcesrv_conn_auth_wait_context);
917 auth_wait->done = true;
918 auth_wait->status = status;
920 if (auth_wait->req == NULL) {
924 if (tevent_req_nterror(auth_wait->req, status)) {
928 tevent_req_done(auth_wait->req);
931 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
933 static void dcesrv_bind_done(struct tevent_req *subreq);
936 handle a bind request
938 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
940 struct dcesrv_connection *conn = call->conn;
941 struct ncacn_packet *pkt = &call->ack_pkt;
943 uint32_t extra_flags = 0;
944 uint16_t max_req = 0;
945 uint16_t max_rep = 0;
946 struct dcerpc_binding *ep_2nd_description = NULL;
947 const char *endpoint = NULL;
948 struct dcesrv_auth *auth = call->auth_state;
949 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
950 struct dcerpc_ack_ctx *ack_features = NULL;
951 struct tevent_req *subreq = NULL;
954 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
956 call->pkt.u.bind.auth_info.length,
957 0, /* required flags */
958 DCERPC_PFC_FLAG_FIRST |
959 DCERPC_PFC_FLAG_LAST |
960 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
961 0x08 | /* this is not defined, but should be ignored */
962 DCERPC_PFC_FLAG_CONC_MPX |
963 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
964 DCERPC_PFC_FLAG_MAYBE |
965 DCERPC_PFC_FLAG_OBJECT_UUID);
966 if (!NT_STATUS_IS_OK(status)) {
967 return dcesrv_bind_nak(call,
968 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
971 /* max_recv_frag and max_xmit_frag result always in the same value! */
972 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
973 call->pkt.u.bind.max_recv_frag);
975 * The values are between 2048 and 5840 tested against Windows 2012R2
976 * via ncacn_ip_tcp on port 135.
978 max_req = MAX(2048, max_req);
979 max_rep = MIN(max_req, call->conn->max_recv_frag);
980 /* They are truncated to an 8 byte boundary. */
983 /* max_recv_frag and max_xmit_frag result always in the same value! */
984 call->conn->max_recv_frag = max_rep;
985 call->conn->max_xmit_frag = max_rep;
987 status = call->conn->dce_ctx->callbacks.assoc_group.find(call);
988 if (!NT_STATUS_IS_OK(status)) {
989 DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
990 call->pkt.u.bind.assoc_group_id, nt_errstr(status));
991 return dcesrv_bind_nak(call, 0);
994 if (call->pkt.u.bind.num_contexts < 1) {
995 return dcesrv_bind_nak(call, 0);
998 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
999 call->pkt.u.bind.num_contexts);
1000 if (ack_ctx_list == NULL) {
1001 return dcesrv_bind_nak(call, 0);
1005 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1006 * dcesrv_check_or_create_context()) and do some protocol validation
1007 * and set sane defaults.
1009 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1010 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1011 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1012 bool is_feature = false;
1013 uint64_t features = 0;
1015 if (c->num_transfer_syntaxes == 0) {
1016 return dcesrv_bind_nak(call, 0);
1019 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1020 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1023 * It's only treated as bind time feature request, if the first
1024 * transfer_syntax matches, all others are ignored.
1026 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1032 if (ack_features != NULL) {
1034 * Only one bind time feature context is allowed.
1036 return dcesrv_bind_nak(call, 0);
1040 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1041 a->reason.negotiate = 0;
1042 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1043 if (call->conn->max_auth_states != 0) {
1044 a->reason.negotiate |=
1045 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1048 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1049 a->reason.negotiate |=
1050 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1053 call->conn->assoc_group->bind_time_features = a->reason.negotiate;
1057 * Try to negotiate one new presentation context.
1059 * Deep in here we locate the iface (by uuid) that the client
1060 * requested, from the list of interfaces on the
1061 * call->conn->endpoint, and call iface->bind() on that iface.
1063 * call->conn was set up at the accept() of the socket, and
1064 * call->conn->endpoint has a list of interfaces restricted to
1065 * this port or pipe.
1067 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1068 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1069 return dcesrv_bind_nak(call, 0);
1071 if (!NT_STATUS_IS_OK(status)) {
1076 * At this point we still don't know which interface (eg
1077 * netlogon, lsa, drsuapi) the caller requested in this bind!
1078 * The most recently added context is available as the first
1079 * element in the linked list at call->conn->contexts, that is
1080 * call->conn->contexts->iface, but they may not have
1081 * requested one at all!
1084 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1085 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1086 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1087 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1090 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1091 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1095 * After finding the interface and setting up the NDR
1096 * transport negotiation etc, handle any authentication that
1097 * is being requested.
1099 if (!dcesrv_auth_bind(call)) {
1101 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1103 * With DCERPC_AUTH_LEVEL_NONE, we get the
1104 * reject_reason in auth->auth_context_id.
1106 return dcesrv_bind_nak(call, auth->auth_context_id);
1110 * This must a be a temporary failure e.g. talloc or invalid
1111 * configuration, e.g. no machine account.
1113 return dcesrv_bind_nak(call,
1114 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1117 /* setup a bind_ack */
1118 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1119 pkt->auth_length = 0;
1120 pkt->call_id = call->pkt.call_id;
1121 pkt->ptype = DCERPC_PKT_BIND_ACK;
1122 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1123 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1124 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1125 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1127 ep_2nd_description = call->conn->endpoint->ep_2nd_description;
1128 if (ep_2nd_description == NULL) {
1129 ep_2nd_description = call->conn->endpoint->ep_description;
1132 endpoint = dcerpc_binding_get_string_option(
1135 if (endpoint == NULL) {
1139 pkt->u.bind_ack.secondary_address = endpoint;
1140 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1141 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1142 pkt->u.bind_ack.auth_info = data_blob_null;
1144 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1145 if (!NT_STATUS_IS_OK(status)) {
1146 return dcesrv_bind_nak(call, 0);
1149 if (auth->auth_finished) {
1150 return dcesrv_auth_reply(call);
1153 subreq = gensec_update_send(call, call->event_ctx,
1154 auth->gensec_security,
1155 call->in_auth_info.credentials);
1156 if (subreq == NULL) {
1157 return NT_STATUS_NO_MEMORY;
1159 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1161 return dcesrv_conn_auth_wait_setup(conn);
1164 static void dcesrv_bind_done(struct tevent_req *subreq)
1166 struct dcesrv_call_state *call =
1167 tevent_req_callback_data(subreq,
1168 struct dcesrv_call_state);
1169 struct dcesrv_connection *conn = call->conn;
1172 status = gensec_update_recv(subreq, call,
1173 &call->out_auth_info->credentials);
1174 TALLOC_FREE(subreq);
1176 status = dcesrv_auth_complete(call, status);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 status = dcesrv_bind_nak(call, 0);
1179 dcesrv_conn_auth_wait_finished(conn, status);
1183 status = dcesrv_auth_reply(call);
1184 dcesrv_conn_auth_wait_finished(conn, status);
1188 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1190 struct ncacn_packet *pkt = &call->ack_pkt;
1191 struct data_blob_list_item *rep = NULL;
1194 rep = talloc_zero(call, struct data_blob_list_item);
1196 return NT_STATUS_NO_MEMORY;
1199 status = dcerpc_ncacn_push_auth(&rep->blob,
1202 call->out_auth_info);
1203 if (!NT_STATUS_IS_OK(status)) {
1207 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1209 DLIST_ADD_END(call->replies, rep);
1210 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1212 if (call->conn->call_list && call->conn->call_list->replies) {
1213 if (call->conn->transport.report_output_data) {
1214 call->conn->transport.report_output_data(call->conn);
1218 return NT_STATUS_OK;
1222 static void dcesrv_auth3_done(struct tevent_req *subreq);
1225 handle a auth3 request
1227 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1229 struct dcesrv_connection *conn = call->conn;
1230 struct dcesrv_auth *auth = call->auth_state;
1231 struct tevent_req *subreq = NULL;
1234 if (!auth->auth_started) {
1235 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1238 if (auth->auth_finished) {
1239 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1242 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1244 call->pkt.u.auth3.auth_info.length,
1245 0, /* required flags */
1246 DCERPC_PFC_FLAG_FIRST |
1247 DCERPC_PFC_FLAG_LAST |
1248 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1249 0x08 | /* this is not defined, but should be ignored */
1250 DCERPC_PFC_FLAG_CONC_MPX |
1251 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1252 DCERPC_PFC_FLAG_MAYBE |
1253 DCERPC_PFC_FLAG_OBJECT_UUID);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1258 /* handle the auth3 in the auth code */
1259 if (!dcesrv_auth_prepare_auth3(call)) {
1261 * we don't send a reply to a auth3 request,
1262 * except by a fault.
1264 * In anycase we mark the connection as
1267 auth->auth_invalid = true;
1268 if (call->fault_code != 0) {
1269 return dcesrv_fault_disconnect(call, call->fault_code);
1272 return NT_STATUS_OK;
1275 subreq = gensec_update_send(call, call->event_ctx,
1276 auth->gensec_security,
1277 call->in_auth_info.credentials);
1278 if (subreq == NULL) {
1279 return NT_STATUS_NO_MEMORY;
1281 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1283 return dcesrv_conn_auth_wait_setup(conn);
1286 static void dcesrv_auth3_done(struct tevent_req *subreq)
1288 struct dcesrv_call_state *call =
1289 tevent_req_callback_data(subreq,
1290 struct dcesrv_call_state);
1291 struct dcesrv_connection *conn = call->conn;
1292 struct dcesrv_auth *auth = call->auth_state;
1295 status = gensec_update_recv(subreq, call,
1296 &call->out_auth_info->credentials);
1297 TALLOC_FREE(subreq);
1299 status = dcesrv_auth_complete(call, status);
1300 if (!NT_STATUS_IS_OK(status)) {
1302 * we don't send a reply to a auth3 request,
1303 * except by a fault.
1305 * In anycase we mark the connection as
1308 auth->auth_invalid = true;
1309 if (call->fault_code != 0) {
1310 status = dcesrv_fault_disconnect(call, call->fault_code);
1311 dcesrv_conn_auth_wait_finished(conn, status);
1315 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1320 * we don't send a reply to a auth3 request.
1323 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1328 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1329 const struct dcerpc_bind *b,
1330 const struct dcerpc_ctx_list *ctx,
1331 struct dcerpc_ack_ctx *ack,
1333 const struct ndr_syntax_id *supported_transfer)
1335 uint32_t if_version;
1336 struct dcesrv_connection_context *context;
1337 const struct dcesrv_interface *iface;
1340 const struct ndr_syntax_id *selected_transfer = NULL;
1345 return NT_STATUS_INTERNAL_ERROR;
1348 return NT_STATUS_INTERNAL_ERROR;
1350 if (ctx->num_transfer_syntaxes < 1) {
1351 return NT_STATUS_INTERNAL_ERROR;
1354 return NT_STATUS_INTERNAL_ERROR;
1356 if (supported_transfer == NULL) {
1357 return NT_STATUS_INTERNAL_ERROR;
1360 switch (ack->result) {
1361 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1362 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1364 * We is already completed.
1366 return NT_STATUS_OK;
1371 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1372 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1374 if_version = ctx->abstract_syntax.if_version;
1375 uuid = ctx->abstract_syntax.uuid;
1377 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1378 if (iface == NULL) {
1379 char *uuid_str = GUID_string(call, &uuid);
1380 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1381 talloc_free(uuid_str);
1383 * We report this only via ack->result
1385 return NT_STATUS_OK;
1388 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1389 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1391 if (validate_only) {
1393 * We report this only via ack->result
1395 return NT_STATUS_OK;
1398 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1400 * we only do NDR encoded dcerpc for now.
1402 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1403 supported_transfer);
1405 selected_transfer = supported_transfer;
1410 context = dcesrv_find_context(call->conn, ctx->context_id);
1411 if (context != NULL) {
1412 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1413 &ctx->abstract_syntax);
1415 return NT_STATUS_RPC_PROTOCOL_ERROR;
1418 if (selected_transfer != NULL) {
1419 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1422 return NT_STATUS_RPC_PROTOCOL_ERROR;
1425 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1426 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1427 ack->syntax = context->transfer_syntax;
1431 * We report this only via ack->result
1433 return NT_STATUS_OK;
1436 if (selected_transfer == NULL) {
1438 * We report this only via ack->result
1440 return NT_STATUS_OK;
1443 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1444 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1446 /* add this context to the list of available context_ids */
1447 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1448 if (context == NULL) {
1449 return NT_STATUS_NO_MEMORY;
1451 context->conn = call->conn;
1452 context->context_id = ctx->context_id;
1453 context->iface = iface;
1454 context->transfer_syntax = *selected_transfer;
1455 DLIST_ADD(call->conn->contexts, context);
1456 call->context = context;
1457 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1459 dcesrv_prepare_context_auth(call);
1462 * Multiplex is supported by default
1464 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1466 status = iface->bind(context, iface);
1467 call->context = NULL;
1468 if (!NT_STATUS_IS_OK(status)) {
1469 /* we don't want to trigger the iface->unbind() hook */
1470 context->iface = NULL;
1471 talloc_free(context);
1473 * We report this only via ack->result
1475 return NT_STATUS_OK;
1478 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1479 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1480 ack->syntax = context->transfer_syntax;
1481 return NT_STATUS_OK;
1484 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1485 const struct dcerpc_bind *b,
1486 struct dcerpc_ack_ctx *ack_ctx_list)
1490 bool validate_only = false;
1491 bool preferred_ndr32;
1494 * Try to negotiate one new presentation context,
1495 * using our preferred transfer syntax.
1497 for (i = 0; i < b->num_contexts; i++) {
1498 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1499 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1501 status = dcesrv_check_or_create_context(call, b, c, a,
1503 call->conn->preferred_transfer);
1504 if (!NT_STATUS_IS_OK(status)) {
1508 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1510 * We managed to negotiate one context.
1514 validate_only = true;
1518 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1519 call->conn->preferred_transfer);
1520 if (preferred_ndr32) {
1524 return NT_STATUS_OK;
1528 * Try to negotiate one new presentation context,
1529 * using NDR 32 as fallback.
1531 for (i = 0; i < b->num_contexts; i++) {
1532 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1533 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1535 status = dcesrv_check_or_create_context(call, b, c, a,
1537 &ndr_transfer_syntax_ndr);
1538 if (!NT_STATUS_IS_OK(status)) {
1542 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1544 * We managed to negotiate one context.
1548 validate_only = true;
1552 return NT_STATUS_OK;
1555 static void dcesrv_alter_done(struct tevent_req *subreq);
1558 handle a alter context request
1560 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1562 struct dcesrv_connection *conn = call->conn;
1564 bool auth_ok = false;
1565 struct ncacn_packet *pkt = &call->ack_pkt;
1566 uint32_t extra_flags = 0;
1567 struct dcesrv_auth *auth = call->auth_state;
1568 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1569 struct tevent_req *subreq = NULL;
1572 if (!call->conn->allow_alter) {
1573 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1576 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1578 call->pkt.u.alter.auth_info.length,
1579 0, /* required flags */
1580 DCERPC_PFC_FLAG_FIRST |
1581 DCERPC_PFC_FLAG_LAST |
1582 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1583 0x08 | /* this is not defined, but should be ignored */
1584 DCERPC_PFC_FLAG_CONC_MPX |
1585 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1586 DCERPC_PFC_FLAG_MAYBE |
1587 DCERPC_PFC_FLAG_OBJECT_UUID);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1592 auth_ok = dcesrv_auth_alter(call);
1594 if (call->fault_code != 0) {
1595 return dcesrv_fault_disconnect(call, call->fault_code);
1599 if (call->pkt.u.alter.num_contexts < 1) {
1600 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1603 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1604 call->pkt.u.alter.num_contexts);
1605 if (ack_ctx_list == NULL) {
1606 return NT_STATUS_NO_MEMORY;
1610 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1611 * dcesrv_check_or_create_context()) and do some protocol validation
1612 * and set sane defaults.
1614 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1615 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1616 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1618 if (c->num_transfer_syntaxes == 0) {
1619 return dcesrv_fault_disconnect(call,
1620 DCERPC_NCA_S_PROTO_ERROR);
1623 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1624 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1628 * Try to negotiate one new presentation context.
1630 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1631 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1632 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1634 if (!NT_STATUS_IS_OK(status)) {
1638 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1639 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1640 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1641 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1644 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1645 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1648 /* handle any authentication that is being requested */
1650 if (call->in_auth_info.auth_type != auth->auth_type) {
1651 return dcesrv_fault_disconnect(call,
1652 DCERPC_FAULT_SEC_PKG_ERROR);
1654 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1657 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1658 pkt->auth_length = 0;
1659 pkt->call_id = call->pkt.call_id;
1660 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1661 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1662 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1663 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1664 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1665 pkt->u.alter_resp.secondary_address = "";
1666 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1667 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1668 pkt->u.alter_resp.auth_info = data_blob_null;
1670 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1671 if (!NT_STATUS_IS_OK(status)) {
1672 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1675 if (auth->auth_finished) {
1676 return dcesrv_auth_reply(call);
1679 subreq = gensec_update_send(call, call->event_ctx,
1680 auth->gensec_security,
1681 call->in_auth_info.credentials);
1682 if (subreq == NULL) {
1683 return NT_STATUS_NO_MEMORY;
1685 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1687 return dcesrv_conn_auth_wait_setup(conn);
1690 static void dcesrv_alter_done(struct tevent_req *subreq)
1692 struct dcesrv_call_state *call =
1693 tevent_req_callback_data(subreq,
1694 struct dcesrv_call_state);
1695 struct dcesrv_connection *conn = call->conn;
1698 status = gensec_update_recv(subreq, call,
1699 &call->out_auth_info->credentials);
1700 TALLOC_FREE(subreq);
1702 status = dcesrv_auth_complete(call, status);
1703 if (!NT_STATUS_IS_OK(status)) {
1704 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1705 dcesrv_conn_auth_wait_finished(conn, status);
1709 status = dcesrv_auth_reply(call);
1710 dcesrv_conn_auth_wait_finished(conn, status);
1715 possibly save the call for inspection with ndrdump
1717 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1720 dcerpc_log_packet(call->conn->packet_log_dir,
1721 call->context->iface->name,
1722 call->pkt.u.request.opnum,
1724 &call->pkt.u.request.stub_and_verifier,
1731 Save the call for use as a seed for fuzzing.
1733 This is only enabled in a developer build, and only has effect if the
1734 "dcesrv fuzz directory" param is set.
1736 void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob,
1737 struct dcesrv_call_state *call,
1740 const char *dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx,
1742 "dcesrv", "fuzz directory");
1744 dcerpc_save_ndr_fuzz_seed(call,
1747 call->context->iface->name,
1749 call->pkt.u.request.opnum,
1750 call->ndr_pull->flags & LIBNDR_FLAG_NDR64);
1752 #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1755 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1757 TALLOC_CTX *frame = talloc_stackframe();
1758 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1759 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1760 const struct dcerpc_sec_vt_pcontext pcontext = {
1761 .abstract_syntax = call->context->iface->syntax_id,
1762 .transfer_syntax = call->context->transfer_syntax,
1764 const struct dcerpc_sec_vt_header2 header2 =
1765 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1766 enum ndr_err_code ndr_err;
1767 struct dcerpc_sec_verification_trailer *vt = NULL;
1768 NTSTATUS status = NT_STATUS_OK;
1771 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1773 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1776 status = ndr_map_error2ntstatus(ndr_err);
1780 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1781 &pcontext, &header2);
1783 status = NT_STATUS_ACCESS_DENIED;
1792 handle a dcerpc request packet
1794 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1796 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1797 struct dcesrv_auth *auth = call->auth_state;
1798 enum dcerpc_transport_t transport =
1799 dcerpc_binding_get_transport(endpoint->ep_description);
1800 struct ndr_pull *pull;
1803 if (!auth->auth_finished) {
1804 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1807 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1808 if (auth->gensec_security != NULL &&
1809 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1810 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1813 if (call->context == NULL) {
1814 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1815 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1818 switch (auth->auth_level) {
1819 case DCERPC_AUTH_LEVEL_NONE:
1820 case DCERPC_AUTH_LEVEL_PACKET:
1821 case DCERPC_AUTH_LEVEL_INTEGRITY:
1822 case DCERPC_AUTH_LEVEL_PRIVACY:
1825 if (!call->context->allow_connect) {
1828 addr = tsocket_address_string(call->conn->remote_address,
1831 DEBUG(2, ("%s: restrict auth_level_connect access "
1832 "to [%s] with auth[type=0x%x,level=0x%x] "
1833 "on [%s] from [%s]\n",
1834 __func__, call->context->iface->name,
1837 derpc_transport_string_by_transport(transport),
1839 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1844 if (auth->auth_level < call->context->min_auth_level) {
1847 addr = tsocket_address_string(call->conn->remote_address, call);
1849 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1850 "to [%s] with auth[type=0x%x,level=0x%x] "
1851 "on [%s] from [%s]\n",
1853 call->context->min_auth_level,
1854 call->context->iface->name,
1857 derpc_transport_string_by_transport(transport),
1859 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1862 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1863 NT_STATUS_HAVE_NO_MEMORY(pull);
1865 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1867 call->ndr_pull = pull;
1869 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1870 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1873 status = dcesrv_check_verification_trailer(call);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 uint32_t faultcode = DCERPC_FAULT_OTHER;
1876 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1877 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1879 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1880 nt_errstr(status)));
1881 return dcesrv_fault(call, faultcode);
1884 /* unravel the NDR for the packet */
1885 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1886 if (!NT_STATUS_IS_OK(status)) {
1887 uint8_t extra_flags = 0;
1888 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1889 /* we got an unknown call */
1890 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1891 call->pkt.u.request.opnum,
1892 call->context->iface->name));
1893 dcesrv_save_call(call, "unknown");
1894 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1896 dcesrv_save_call(call, "pullfail");
1899 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1902 dcesrv_save_ndr_fuzz_seed(call->pkt.u.request.stub_and_verifier,
1906 if (pull->offset != pull->data_size) {
1907 dcesrv_save_call(call, "extrabytes");
1908 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1909 pull->data_size - pull->offset));
1912 /* call the dispatch function */
1913 status = call->context->iface->dispatch(call, call, call->r);
1914 if (!NT_STATUS_IS_OK(status)) {
1915 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1916 call->context->iface->name,
1917 call->pkt.u.request.opnum,
1918 dcerpc_errstr(pull, call->fault_code)));
1919 return dcesrv_fault(call, call->fault_code);
1922 /* add the call to the pending list */
1923 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1925 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1926 return NT_STATUS_OK;
1929 return dcesrv_reply(call);
1934 remove the call from the right list when freed
1936 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1938 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1942 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1944 return conn->local_address;
1947 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1949 return conn->remote_address;
1953 process some input to a dcerpc endpoint server.
1955 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1956 struct ncacn_packet *pkt,
1960 struct dcesrv_call_state *call;
1961 struct dcesrv_call_state *existing = NULL;
1962 size_t num_auth_ctx = 0;
1963 enum dcerpc_AuthType auth_type = 0;
1964 enum dcerpc_AuthLevel auth_level = 0;
1965 uint32_t auth_context_id = 0;
1967 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1969 data_blob_free(&blob);
1971 return NT_STATUS_NO_MEMORY;
1973 call->conn = dce_conn;
1974 call->event_ctx = dce_conn->event_ctx;
1975 call->state_flags = call->conn->state_flags;
1976 call->time = timeval_current();
1977 call->list = DCESRV_LIST_NONE;
1979 talloc_steal(call, pkt);
1980 talloc_steal(call, blob.data);
1983 if (dce_conn->max_auth_states == 0) {
1984 call->auth_state = dce_conn->default_auth_state;
1985 } else if (call->pkt.auth_length == 0) {
1986 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1987 dce_conn->default_auth_level_connect != NULL)
1989 call->auth_state = dce_conn->default_auth_level_connect;
1991 call->auth_state = dce_conn->default_auth_state;
1995 if (call->auth_state == NULL) {
1996 struct dcesrv_auth *a = NULL;
1998 auth_type = dcerpc_get_auth_type(&blob);
1999 auth_level = dcerpc_get_auth_level(&blob);
2000 auth_context_id = dcerpc_get_auth_context_id(&blob);
2002 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2003 dce_conn->default_auth_level_connect = NULL;
2004 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
2005 dce_conn->got_explicit_auth_level_connect = true;
2009 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2012 if (a->auth_type != auth_type) {
2015 if (a->auth_finished && a->auth_level != auth_level) {
2018 if (a->auth_context_id != auth_context_id) {
2022 DLIST_PROMOTE(dce_conn->auth_states, a);
2023 call->auth_state = a;
2028 if (call->auth_state == NULL) {
2029 struct dcesrv_auth *a = NULL;
2031 if (num_auth_ctx >= dce_conn->max_auth_states) {
2032 return dcesrv_fault_disconnect(call,
2033 DCERPC_NCA_S_PROTO_ERROR);
2036 a = dcesrv_auth_create(dce_conn);
2039 return NT_STATUS_NO_MEMORY;
2041 DLIST_ADD(dce_conn->auth_states, a);
2042 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2044 * This can never be valid.
2046 a->auth_invalid = true;
2048 call->auth_state = a;
2051 talloc_set_destructor(call, dcesrv_call_dequeue);
2053 if (call->conn->allow_bind) {
2055 * Only one bind is possible per connection
2057 call->conn->allow_bind = false;
2058 return dcesrv_bind(call);
2061 /* we have to check the signing here, before combining the
2063 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2064 dcesrv_default_auth_state_prepare_request(call);
2066 if (call->auth_state->auth_started &&
2067 !call->auth_state->auth_finished) {
2068 return dcesrv_fault_disconnect(call,
2069 DCERPC_NCA_S_PROTO_ERROR);
2072 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2074 call->pkt.u.request.stub_and_verifier.length,
2075 0, /* required_flags */
2076 DCERPC_PFC_FLAG_FIRST |
2077 DCERPC_PFC_FLAG_LAST |
2078 DCERPC_PFC_FLAG_PENDING_CANCEL |
2079 0x08 | /* this is not defined, but should be ignored */
2080 DCERPC_PFC_FLAG_CONC_MPX |
2081 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2082 DCERPC_PFC_FLAG_MAYBE |
2083 DCERPC_PFC_FLAG_OBJECT_UUID);
2084 if (!NT_STATUS_IS_OK(status)) {
2085 return dcesrv_fault_disconnect(call,
2086 DCERPC_NCA_S_PROTO_ERROR);
2089 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2091 * We don't use dcesrv_fault_disconnect()
2092 * here, because we don't want to set
2093 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2095 * Note that we don't check against the negotiated
2096 * max_recv_frag, but a hard coded value.
2098 dcesrv_call_disconnect_after(call,
2099 "dcesrv_auth_request - frag_length too large");
2100 return dcesrv_fault(call,
2101 DCERPC_NCA_S_PROTO_ERROR);
2104 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2105 if (dce_conn->pending_call_list != NULL) {
2107 * concurrent requests are only allowed
2108 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2110 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2111 dcesrv_call_disconnect_after(call,
2112 "dcesrv_auth_request - "
2113 "existing pending call without CONN_MPX");
2114 return dcesrv_fault(call,
2115 DCERPC_NCA_S_PROTO_ERROR);
2118 /* only one request is possible in the fragmented list */
2119 if (dce_conn->incoming_fragmented_call_list != NULL) {
2120 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2122 * Without DCERPC_PFC_FLAG_CONC_MPX
2123 * we need to return the FAULT on the
2124 * already existing call.
2126 * This is important to get the
2127 * call_id and context_id right.
2130 call = dce_conn->incoming_fragmented_call_list;
2132 dcesrv_call_disconnect_after(call,
2133 "dcesrv_auth_request - "
2134 "existing fragmented call");
2135 return dcesrv_fault(call,
2136 DCERPC_NCA_S_PROTO_ERROR);
2138 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2139 return dcesrv_fault_disconnect(call,
2140 DCERPC_FAULT_NO_CALL_ACTIVE);
2142 call->context = dcesrv_find_context(call->conn,
2143 call->pkt.u.request.context_id);
2144 if (call->context == NULL) {
2145 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2146 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2149 const struct dcerpc_request *nr = &call->pkt.u.request;
2150 const struct dcerpc_request *er = NULL;
2153 existing = dcesrv_find_fragmented_call(dce_conn,
2155 if (existing == NULL) {
2156 dcesrv_call_disconnect_after(call,
2157 "dcesrv_auth_request - "
2158 "no existing fragmented call");
2159 return dcesrv_fault(call,
2160 DCERPC_NCA_S_PROTO_ERROR);
2162 er = &existing->pkt.u.request;
2164 if (call->pkt.ptype != existing->pkt.ptype) {
2165 /* trying to play silly buggers are we? */
2166 return dcesrv_fault_disconnect(existing,
2167 DCERPC_NCA_S_PROTO_ERROR);
2169 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2172 return dcesrv_fault_disconnect(existing,
2173 DCERPC_NCA_S_PROTO_ERROR);
2175 if (nr->context_id != er->context_id) {
2176 return dcesrv_fault_disconnect(existing,
2177 DCERPC_NCA_S_PROTO_ERROR);
2179 if (nr->opnum != er->opnum) {
2180 return dcesrv_fault_disconnect(existing,
2181 DCERPC_NCA_S_PROTO_ERROR);
2186 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2188 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2190 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2191 payload_offset += 16;
2194 ok = dcesrv_auth_pkt_pull(call, &blob,
2195 0, /* required_flags */
2196 DCERPC_PFC_FLAG_FIRST |
2197 DCERPC_PFC_FLAG_LAST |
2198 DCERPC_PFC_FLAG_PENDING_CANCEL |
2199 0x08 | /* this is not defined, but should be ignored */
2200 DCERPC_PFC_FLAG_CONC_MPX |
2201 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2202 DCERPC_PFC_FLAG_MAYBE |
2203 DCERPC_PFC_FLAG_OBJECT_UUID,
2205 &call->pkt.u.request.stub_and_verifier);
2208 * We don't use dcesrv_fault_disconnect()
2209 * here, because we don't want to set
2210 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2212 dcesrv_call_disconnect_after(call,
2213 "dcesrv_auth_request - failed");
2214 if (call->fault_code == 0) {
2215 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2217 return dcesrv_fault(call, call->fault_code);
2221 /* see if this is a continued packet */
2222 if (existing != NULL) {
2223 struct dcerpc_request *er = &existing->pkt.u.request;
2224 const struct dcerpc_request *nr = &call->pkt.u.request;
2230 * Up to 4 MByte are allowed by all fragments
2232 available = dce_conn->max_total_request_size;
2233 if (er->stub_and_verifier.length > available) {
2234 dcesrv_call_disconnect_after(existing,
2235 "dcesrv_auth_request - existing payload too large");
2236 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2238 available -= er->stub_and_verifier.length;
2239 if (nr->alloc_hint > available) {
2240 dcesrv_call_disconnect_after(existing,
2241 "dcesrv_auth_request - alloc hint too large");
2242 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2244 if (nr->stub_and_verifier.length > available) {
2245 dcesrv_call_disconnect_after(existing,
2246 "dcesrv_auth_request - new payload too large");
2247 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2249 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2250 /* allocate at least 1 byte */
2251 alloc_hint = MAX(alloc_hint, 1);
2252 alloc_size = er->stub_and_verifier.length +
2253 nr->stub_and_verifier.length;
2254 alloc_size = MAX(alloc_size, alloc_hint);
2256 er->stub_and_verifier.data =
2257 talloc_realloc(existing,
2258 er->stub_and_verifier.data,
2259 uint8_t, alloc_size);
2260 if (er->stub_and_verifier.data == NULL) {
2262 return dcesrv_fault_with_flags(existing,
2263 DCERPC_FAULT_OUT_OF_RESOURCES,
2264 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2266 memcpy(er->stub_and_verifier.data +
2267 er->stub_and_verifier.length,
2268 nr->stub_and_verifier.data,
2269 nr->stub_and_verifier.length);
2270 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2272 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2278 /* this may not be the last pdu in the chain - if its isn't then
2279 just put it on the incoming_fragmented_call_list and wait for the rest */
2280 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2281 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2283 * Up to 4 MByte are allowed by all fragments
2285 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2286 dcesrv_call_disconnect_after(call,
2287 "dcesrv_auth_request - initial alloc hint too large");
2288 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2290 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2291 return NT_STATUS_OK;
2294 /* This removes any fragments we may have had stashed away */
2295 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2297 switch (call->pkt.ptype) {
2298 case DCERPC_PKT_BIND:
2299 status = dcesrv_bind_nak(call,
2300 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2302 case DCERPC_PKT_AUTH3:
2303 status = dcesrv_auth3(call);
2305 case DCERPC_PKT_ALTER:
2306 status = dcesrv_alter(call);
2308 case DCERPC_PKT_REQUEST:
2309 status = dcesrv_request(call);
2311 case DCERPC_PKT_CO_CANCEL:
2312 case DCERPC_PKT_ORPHANED:
2314 * Window just ignores CO_CANCEL and ORPHANED,
2317 status = NT_STATUS_OK;
2320 case DCERPC_PKT_BIND_ACK:
2321 case DCERPC_PKT_BIND_NAK:
2322 case DCERPC_PKT_ALTER_RESP:
2323 case DCERPC_PKT_RESPONSE:
2324 case DCERPC_PKT_FAULT:
2325 case DCERPC_PKT_SHUTDOWN:
2327 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2331 /* if we are going to be sending a reply then add
2332 it to the list of pending calls. We add it to the end to keep the call
2333 list in the order we will answer */
2334 if (!NT_STATUS_IS_OK(status)) {
2341 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2342 struct loadparm_context *lp_ctx,
2343 struct dcesrv_context_callbacks *cb,
2344 struct dcesrv_context **_dce_ctx)
2346 struct dcesrv_context *dce_ctx;
2348 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2349 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2351 if (uid_wrapper_enabled()) {
2352 setenv("UID_WRAPPER_MYUID", "1", 1);
2354 dce_ctx->initial_euid = geteuid();
2355 if (uid_wrapper_enabled()) {
2356 unsetenv("UID_WRAPPER_MYUID");
2359 dce_ctx->endpoint_list = NULL;
2360 dce_ctx->lp_ctx = lp_ctx;
2361 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2362 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2363 dce_ctx->broken_connections = NULL;
2365 dce_ctx->callbacks = *cb;
2368 *_dce_ctx = dce_ctx;
2369 return NT_STATUS_OK;
2372 _PUBLIC_ NTSTATUS dcesrv_reinit_context(struct dcesrv_context *dce_ctx)
2376 status = dcesrv_shutdown_registered_ep_servers(dce_ctx);
2377 if (!NT_STATUS_IS_OK(status)) {
2381 /* Clear endpoints */
2382 while (dce_ctx->endpoint_list != NULL) {
2383 struct dcesrv_endpoint *e = dce_ctx->endpoint_list;
2384 DLIST_REMOVE(dce_ctx->endpoint_list, e);
2388 /* Remove broken connections */
2389 dcesrv_cleanup_broken_connections(dce_ctx);
2391 /* Reinit assoc group idr */
2392 TALLOC_FREE(dce_ctx->assoc_groups_idr);
2393 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2394 if (dce_ctx->assoc_groups_idr == NULL) {
2395 return NT_STATUS_NO_MEMORY;
2398 return NT_STATUS_OK;
2401 _PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
2402 const char **endpoint_servers)
2407 if (endpoint_servers == NULL) {
2408 DBG_ERR("No endpoint servers configured\n");
2409 return NT_STATUS_INTERNAL_ERROR;
2412 for (i=0;endpoint_servers[i];i++) {
2413 status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]);
2414 if (!NT_STATUS_IS_OK(status)) {
2415 DBG_ERR("failed to init endpoint server = '%s': %s\n",
2416 endpoint_servers[i], nt_errstr(status));
2421 return NT_STATUS_OK;
2424 /* the list of currently registered DCERPC endpoint servers.
2426 static struct ep_server {
2427 struct dcesrv_endpoint_server *ep_server;
2428 } *ep_servers = NULL;
2429 static int num_ep_servers = 0;
2431 _PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers(
2432 struct dcesrv_context *dce_ctx)
2437 for (i = 0; i < num_ep_servers; i++) {
2438 status = dcesrv_init_ep_server(dce_ctx,
2439 ep_servers[i].ep_server->name);
2440 if (!NT_STATUS_IS_OK(status)) {
2445 return NT_STATUS_OK;
2448 _PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
2449 const char *ep_server_name)
2451 struct dcesrv_endpoint_server *ep_server = NULL;
2454 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2455 dcesrv_ep_server_byname(ep_server_name));
2456 if (ep_server == NULL) {
2457 DBG_ERR("Failed to find endpoint server '%s'\n",
2459 return NT_STATUS_INTERNAL_ERROR;
2462 if (ep_server->initialized) {
2463 return NT_STATUS_OK;
2466 status = ep_server->init_server(dce_ctx, ep_server);
2467 if (!NT_STATUS_IS_OK(status)) {
2468 DBG_ERR("Failed to init endpoint server '%s': %s\n",
2469 ep_server_name, nt_errstr(status));
2473 ep_server->initialized = true;
2475 return NT_STATUS_OK;
2478 _PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers(
2479 struct dcesrv_context *dce_ctx)
2484 for (i = 0; i < num_ep_servers; i++) {
2485 status = dcesrv_shutdown_ep_server(dce_ctx,
2486 ep_servers[i].ep_server->name);
2487 if (!NT_STATUS_IS_OK(status)) {
2492 return NT_STATUS_OK;
2495 _PUBLIC_ NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
2496 const char *ep_server_name)
2498 struct dcesrv_endpoint_server *ep_server = NULL;
2501 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2502 dcesrv_ep_server_byname(ep_server_name));
2503 if (ep_server == NULL) {
2504 DBG_ERR("Failed to find endpoint server '%s'\n",
2506 return NT_STATUS_INTERNAL_ERROR;
2509 if (!ep_server->initialized) {
2510 return NT_STATUS_OK;
2513 DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2516 status = ep_server->shutdown_server(dce_ctx, ep_server);
2517 if (!NT_STATUS_IS_OK(status)) {
2518 DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2519 ep_server_name, nt_errstr(status));
2523 ep_server->initialized = false;
2525 return NT_STATUS_OK;
2529 register a DCERPC endpoint server.
2531 The 'name' can be later used by other backends to find the operations
2532 structure for this backend.
2535 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2538 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2539 /* its already registered! */
2540 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2542 return NT_STATUS_OBJECT_NAME_COLLISION;
2545 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2547 smb_panic("out of memory in dcerpc_register");
2550 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2551 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2555 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2558 return NT_STATUS_OK;
2562 return the operations structure for a named backend of the specified type
2564 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2568 for (i=0;i<num_ep_servers;i++) {
2569 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2570 return ep_servers[i].ep_server;
2578 return the DCERPC module version, and the size of some critical types
2579 This can be used by endpoint server modules to either detect compilation errors, or provide
2580 multiple implementations for different smbd compilation options in one module
2582 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2584 static const struct dcesrv_critical_sizes critical_sizes = {
2585 DCERPC_MODULE_VERSION,
2586 sizeof(struct dcesrv_context),
2587 sizeof(struct dcesrv_endpoint),
2588 sizeof(struct dcesrv_endpoint_server),
2589 sizeof(struct dcesrv_interface),
2590 sizeof(struct dcesrv_if_list),
2591 sizeof(struct dcesrv_connection),
2592 sizeof(struct dcesrv_call_state),
2593 sizeof(struct dcesrv_auth),
2594 sizeof(struct dcesrv_handle)
2597 return &critical_sizes;
2600 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2602 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2603 struct dcesrv_auth *a = NULL;
2605 dce_conn->wait_send = NULL;
2606 dce_conn->wait_recv = NULL;
2607 dce_conn->wait_private = NULL;
2609 dce_conn->allow_bind = false;
2610 dce_conn->allow_alter = false;
2612 dce_conn->default_auth_state->auth_invalid = true;
2614 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2615 a->auth_invalid = true;
2618 if (dce_conn->pending_call_list == NULL) {
2619 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2621 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2622 dce_conn->transport.terminate_connection(dce_conn,
2623 full_reason ? full_reason : reason);
2627 if (dce_conn->terminate != NULL) {
2631 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2633 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2634 if (dce_conn->terminate == NULL) {
2635 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2637 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2640 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2642 struct dcesrv_connection *cur, *next;
2644 next = dce_ctx->broken_connections;
2645 while (next != NULL) {
2649 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2650 struct dcesrv_connection_context *context_cur, *context_next;
2652 context_next = cur->contexts;
2653 while (context_next != NULL) {
2654 context_cur = context_next;
2655 context_next = context_cur->next;
2657 dcesrv_connection_context_destructor(context_cur);
2661 dcesrv_terminate_connection(cur, cur->terminate);
2665 /* We need this include to be able to compile on some plateforms
2666 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2668 * It has to be that deep because otherwise we have a conflict on
2669 * const struct dcesrv_interface declaration.
2670 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2671 * which conflict with the bind used before.
2673 #include "system/network.h"
2675 struct dcesrv_sock_reply_state {
2676 struct dcesrv_connection *dce_conn;
2677 struct dcesrv_call_state *call;
2681 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2682 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2684 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2686 struct dcesrv_call_state *call;
2688 call = dce_conn->call_list;
2689 if (!call || !call->replies) {
2693 while (call->replies) {
2694 struct data_blob_list_item *rep = call->replies;
2695 struct dcesrv_sock_reply_state *substate;
2696 struct tevent_req *subreq;
2698 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2700 dcesrv_terminate_connection(dce_conn, "no memory");
2704 substate->dce_conn = dce_conn;
2705 substate->call = NULL;
2707 DLIST_REMOVE(call->replies, rep);
2709 if (call->replies == NULL && call->terminate_reason == NULL) {
2710 substate->call = call;
2713 substate->iov.iov_base = (void *) rep->blob.data;
2714 substate->iov.iov_len = rep->blob.length;
2716 subreq = tstream_writev_queue_send(substate,
2717 dce_conn->event_ctx,
2719 dce_conn->send_queue,
2722 dcesrv_terminate_connection(dce_conn, "no memory");
2725 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2729 if (call->terminate_reason != NULL) {
2730 struct tevent_req *subreq;
2732 subreq = tevent_queue_wait_send(call,
2733 dce_conn->event_ctx,
2734 dce_conn->send_queue);
2736 dcesrv_terminate_connection(dce_conn, __location__);
2739 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2743 DLIST_REMOVE(call->conn->call_list, call);
2744 call->list = DCESRV_LIST_NONE;
2747 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2749 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2750 struct dcesrv_sock_reply_state);
2754 struct dcesrv_call_state *call = substate->call;
2756 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2757 TALLOC_FREE(subreq);
2759 status = map_nt_error_from_unix_common(sys_errno);
2760 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2764 talloc_free(substate);
2770 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2772 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2774 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2775 struct dcesrv_call_state);
2779 /* make sure we stop send queue before removing subreq */
2780 tevent_queue_stop(call->conn->send_queue);
2782 ok = tevent_queue_wait_recv(subreq);
2783 TALLOC_FREE(subreq);
2785 dcesrv_terminate_connection(call->conn, __location__);
2789 /* disconnect after 200 usecs */
2790 tv = timeval_current_ofs_usec(200);
2791 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2792 if (subreq == NULL) {
2793 dcesrv_terminate_connection(call->conn, __location__);
2796 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2800 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2802 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2803 struct dcesrv_call_state);
2806 ok = tevent_wakeup_recv(subreq);
2807 TALLOC_FREE(subreq);
2809 dcesrv_terminate_connection(call->conn, __location__);
2813 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2816 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2818 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2820 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2821 struct dcesrv_connection);
2822 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2823 struct ncacn_packet *pkt;
2827 if (dce_conn->terminate) {
2829 * if the current connection is broken
2830 * we need to clean it up before any other connection
2832 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2833 dcesrv_cleanup_broken_connections(dce_ctx);
2837 dcesrv_cleanup_broken_connections(dce_ctx);
2839 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2841 TALLOC_FREE(subreq);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2847 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2848 if (!NT_STATUS_IS_OK(status)) {
2849 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2854 * This is used to block the connection during
2855 * pending authentication.
2857 if (dce_conn->wait_send != NULL) {
2858 subreq = dce_conn->wait_send(dce_conn,
2859 dce_conn->event_ctx,
2860 dce_conn->wait_private);
2862 status = NT_STATUS_NO_MEMORY;
2863 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2866 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2870 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2871 dce_conn->event_ctx,
2874 status = NT_STATUS_NO_MEMORY;
2875 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2878 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2881 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2883 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2884 struct dcesrv_connection);
2885 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2888 if (dce_conn->terminate) {
2890 * if the current connection is broken
2891 * we need to clean it up before any other connection
2893 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2894 dcesrv_cleanup_broken_connections(dce_ctx);
2898 dcesrv_cleanup_broken_connections(dce_ctx);
2900 status = dce_conn->wait_recv(subreq);
2901 dce_conn->wait_send = NULL;
2902 dce_conn->wait_recv = NULL;
2903 dce_conn->wait_private = NULL;
2904 TALLOC_FREE(subreq);
2905 if (!NT_STATUS_IS_OK(status)) {
2906 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2910 status = dcesrv_connection_loop_start(dce_conn);
2911 if (!NT_STATUS_IS_OK(status)) {
2912 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2918 * retrieve credentials from a dce_call
2920 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2922 struct dcesrv_auth *auth = dce_call->auth_state;
2923 SMB_ASSERT(auth->auth_finished);
2924 return auth->session_info->credentials;
2928 * returns true if this is an authenticated call
2930 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2932 struct dcesrv_auth *auth = dce_call->auth_state;
2933 enum security_user_level level;
2934 SMB_ASSERT(auth->auth_finished);
2935 level = security_session_user_level(auth->session_info, NULL);
2936 return level >= SECURITY_USER;
2940 * retrieve account_name for a dce_call
2942 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2944 struct dcesrv_auth *auth = dce_call->auth_state;
2945 SMB_ASSERT(auth->auth_finished);
2946 return auth->session_info->info->account_name;
2950 * retrieve session_info from a dce_call
2952 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
2954 struct dcesrv_auth *auth = dce_call->auth_state;
2955 SMB_ASSERT(auth->auth_finished);
2956 return auth->session_info;
2960 * retrieve auth type/level from a dce_call
2962 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
2963 enum dcerpc_AuthType *auth_type,
2964 enum dcerpc_AuthLevel *auth_level)
2966 struct dcesrv_auth *auth = dce_call->auth_state;
2968 SMB_ASSERT(auth->auth_finished);
2970 if (auth_type != NULL) {
2971 *auth_type = auth->auth_type;
2973 if (auth_level != NULL) {
2974 *auth_level = auth->auth_level;
2978 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
2980 struct tevent_req *subreq;
2982 subreq = dcerpc_read_ncacn_packet_send(conn,
2985 if (subreq == NULL) {
2986 return NT_STATUS_NO_MEMORY;
2988 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
2990 return NT_STATUS_OK;