2 Unix SMB/CIFS implementation.
4 server side dcerpc core code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "auth/credentials/credentials.h"
27 #include "lib/util/dlinklist.h"
28 #include "rpc_server/dcerpc_server.h"
29 #include "rpc_server/dcerpc_server_proto.h"
30 #include "system/filesys.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/tsocket/tsocket.h"
34 #include "libcli/named_pipe_auth/npa_tstream.h"
35 #include "smbd/service_stream.h"
36 #include "lib/tsocket/tsocket.h"
37 #include "lib/socket/socket.h"
38 #include "smbd/process_model.h"
39 #include "lib/messaging/irpc.h"
40 #include "librpc/rpc/rpc_common.h"
41 #include "lib/util/samba_modules.h"
42 #include "librpc/gen_ndr/ndr_dcerpc.h"
43 #include "lib/util/tevent_ntstatus.h"
45 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
46 const struct dcerpc_bind *b,
47 struct dcerpc_ack_ctx *ack_ctx_list);
50 take a reference to an existing association group
52 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(struct dcesrv_connection *conn,
55 const struct dcesrv_endpoint *endpoint = conn->endpoint;
56 enum dcerpc_transport_t transport =
57 dcerpc_binding_get_transport(endpoint->ep_description);
58 struct dcesrv_assoc_group *assoc_group;
61 /* find an association group given a assoc_group_id */
62 id_ptr = idr_find(conn->dce_ctx->assoc_groups_idr, id);
64 DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id);
67 assoc_group = talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
69 if (assoc_group->transport != transport) {
71 derpc_transport_string_by_transport(
72 assoc_group->transport);
74 derpc_transport_string_by_transport(
77 DBG_NOTICE("assoc_group 0x%08x (transport %s) "
78 "is not available on transport %s",
83 return talloc_reference(conn, assoc_group);
86 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
89 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
91 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
98 allocate a new association group
100 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(struct dcesrv_connection *conn)
102 struct dcesrv_context *dce_ctx = conn->dce_ctx;
103 const struct dcesrv_endpoint *endpoint = conn->endpoint;
104 enum dcerpc_transport_t transport =
105 dcerpc_binding_get_transport(endpoint->ep_description);
106 struct dcesrv_assoc_group *assoc_group;
109 assoc_group = talloc_zero(conn, struct dcesrv_assoc_group);
110 if (assoc_group == NULL) {
114 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
116 talloc_free(assoc_group);
117 DEBUG(0,(__location__ ": Out of association groups!\n"));
121 assoc_group->transport = transport;
122 assoc_group->id = id;
123 assoc_group->dce_ctx = dce_ctx;
125 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
130 NTSTATUS dcesrv_assoc_group_find(struct dcesrv_call_state *call)
133 if provided, check the assoc_group is valid
135 if (call->pkt.u.bind.assoc_group_id != 0) {
136 call->conn->assoc_group =
137 dcesrv_assoc_group_reference(call->conn,
138 call->pkt.u.bind.assoc_group_id);
140 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn);
144 * The NETLOGON server does not use handles and so
145 * there is no need to support association groups, but
146 * we need to give back a number regardless.
148 * We have to do this when it is not run as a single process,
149 * because then it can't see the other valid association
150 * groups. We handle this genericly for all endpoints not
151 * running in single process mode.
153 * We know which endpoint we are on even before checking the
154 * iface UUID, so for simplicity we enforce the same policy
155 * for all interfaces on the endpoint.
157 * This means that where NETLOGON
158 * shares an endpoint (such as ncalrpc or of 'lsa over
159 * netlogon' is set) we will still check association groups.
163 if (call->conn->assoc_group == NULL &&
164 !call->conn->endpoint->use_single_process) {
165 call->conn->assoc_group
166 = dcesrv_assoc_group_new(call->conn);
169 if (call->conn->assoc_group == NULL) {
170 /* TODO Return correct status */
171 return NT_STATUS_UNSUCCESSFUL;
178 see if two endpoints match
180 static bool endpoints_match(const struct dcerpc_binding *ep1,
181 const struct dcerpc_binding *ep2)
183 enum dcerpc_transport_t t1;
184 enum dcerpc_transport_t t2;
188 t1 = dcerpc_binding_get_transport(ep1);
189 t2 = dcerpc_binding_get_transport(ep2);
191 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
192 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
202 if (strcasecmp(e1, e2) != 0) {
210 find an endpoint in the dcesrv_context
212 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
213 const struct dcerpc_binding *ep_description)
215 struct dcesrv_endpoint *ep;
216 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
217 if (endpoints_match(ep->ep_description, ep_description)) {
225 find a registered context_id from a bind or alter_context
227 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
230 struct dcesrv_connection_context *c;
231 for (c=conn->contexts;c;c=c->next) {
232 if (c->context_id == context_id) return c;
238 see if a uuid and if_version match to an interface
240 static bool interface_match(const struct dcesrv_interface *if1,
241 const struct dcesrv_interface *if2)
243 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
244 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
248 find the interface operations on any endpoint with this binding
250 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
251 struct dcerpc_binding *binding,
252 const struct dcesrv_interface *iface)
254 struct dcesrv_endpoint *ep;
255 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
256 if (endpoints_match(ep->ep_description, binding)) {
257 struct dcesrv_if_list *ifl;
258 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
259 if (interface_match(&(ifl->iface), iface)) {
260 return &(ifl->iface);
269 see if a uuid and if_version match to an interface
271 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
272 const struct GUID *uuid, uint32_t if_version)
274 return (iface->syntax_id.if_version == if_version &&
275 GUID_equal(&iface->syntax_id.uuid, uuid));
279 find the interface operations on an endpoint by uuid
281 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
282 const struct GUID *uuid, uint32_t if_version)
284 struct dcesrv_if_list *ifl;
285 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
286 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
287 return &(ifl->iface);
294 find the earlier parts of a fragmented call awaiting reassembily
296 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
298 struct dcesrv_call_state *c;
299 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
300 if (c->pkt.call_id == call_id) {
308 register an interface on an endpoint
310 An endpoint is one unix domain socket (for ncalrpc), one TCP port
311 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
313 Each endpoint can have many interfaces such as netlogon, lsa or
314 samr. Some have essentially the full set.
316 This is driven from the set of interfaces listed in each IDL file
317 via the PIDL generated *__op_init_server() functions.
319 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
321 const char *ncacn_np_secondary_endpoint,
322 const struct dcesrv_interface *iface,
323 const struct security_descriptor *sd)
325 struct dcesrv_endpoint *ep;
326 struct dcesrv_if_list *ifl;
327 struct dcerpc_binding *binding;
328 struct dcerpc_binding *binding2 = NULL;
331 enum dcerpc_transport_t transport;
332 char *ep_string = NULL;
333 bool use_single_process = true;
334 const char *ep_process_string;
337 * If we are not using handles, there is no need for force
338 * this service into using a single process.
340 * However, due to the way we listen for RPC packets, we can
341 * only do this if we have a single service per pipe or TCP
342 * port, so we still force a single combined process for
345 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
346 use_single_process = false;
349 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
351 if (NT_STATUS_IS_ERR(status)) {
352 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
356 transport = dcerpc_binding_get_transport(binding);
357 if (transport == NCACN_IP_TCP) {
362 * First check if there is already a port specified, eg
363 * for epmapper on ncacn_ip_tcp:[135]
366 = dcerpc_binding_get_string_option(binding,
368 if (endpoint == NULL) {
369 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
370 "rpc server port", iface->name, 0);
373 * For RPC services that are not set to use a single
374 * process, we do not default to using the 'rpc server
375 * port' because that would cause a double-bind on
378 if (port == 0 && !use_single_process) {
379 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
382 snprintf(port_str, sizeof(port_str), "%u", port);
383 status = dcerpc_binding_set_string_option(binding,
386 if (!NT_STATUS_IS_OK(status)) {
393 if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) {
394 enum dcerpc_transport_t transport2;
396 status = dcerpc_parse_binding(dce_ctx,
397 ncacn_np_secondary_endpoint,
399 if (!NT_STATUS_IS_OK(status)) {
400 DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n",
401 ncacn_np_secondary_endpoint));
405 transport2 = dcerpc_binding_get_transport(binding2);
406 SMB_ASSERT(transport2 == transport);
409 /* see if the interface is already registered on the endpoint */
410 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
411 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
412 iface->name, ep_name));
413 return NT_STATUS_OBJECT_NAME_COLLISION;
416 /* check if this endpoint exists
418 ep = find_endpoint(dce_ctx, binding);
422 * We want a new port on ncacn_ip_tcp for NETLOGON, so
423 * it can be multi-process. Other processes can also
424 * listen on distinct ports, if they have one forced
425 * in the code above with eg 'rpc server port:drsuapi = 1027'
427 * If we have mulitiple endpoints on port 0, they each
428 * get an epemeral port (currently by walking up from
431 * Because one endpoint can only have one process
432 * model, we add a new IP_TCP endpoint for each model.
434 * This works in conjunction with the forced overwrite
435 * of ep->use_single_process below.
437 if (ep->use_single_process != use_single_process
438 && transport == NCACN_IP_TCP) {
443 if (ep == NULL || add_ep) {
444 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
446 return NT_STATUS_NO_MEMORY;
449 ep->ep_description = talloc_move(ep, &binding);
450 ep->ep_2nd_description = talloc_move(ep, &binding2);
453 /* add mgmt interface */
454 ifl = talloc_zero(ep, struct dcesrv_if_list);
456 return NT_STATUS_NO_MEMORY;
459 ifl->iface = dcesrv_get_mgmt_interface();
461 DLIST_ADD(ep->interface_list, ifl);
465 * By default don't force into a single process, but if any
466 * interface on this endpoint on this service uses handles
467 * (most do), then we must force into single process mode
469 * By overwriting this each time a new interface is added to
470 * this endpoint, we end up with the most restrictive setting.
472 if (use_single_process) {
473 ep->use_single_process = true;
476 /* talloc a new interface list element */
477 ifl = talloc_zero(ep, struct dcesrv_if_list);
479 return NT_STATUS_NO_MEMORY;
482 /* copy the given interface struct to the one on the endpoints interface list */
483 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
485 /* if we have a security descriptor given,
486 * we should see if we can set it up on the endpoint
489 /* if there's currently no security descriptor given on the endpoint
492 if (ep->sd == NULL) {
493 ep->sd = security_descriptor_copy(ep, sd);
496 /* if now there's no security descriptor given on the endpoint
497 * something goes wrong, either we failed to copy the security descriptor
498 * or there was already one on the endpoint
500 if (ep->sd != NULL) {
501 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
502 " on endpoint '%s'\n",
503 iface->name, ep_name));
504 if (add_ep) free(ep);
506 return NT_STATUS_OBJECT_NAME_COLLISION;
510 /* finally add the interface on the endpoint */
511 DLIST_ADD(ep->interface_list, ifl);
513 /* if it's a new endpoint add it to the dcesrv_context */
515 DLIST_ADD(dce_ctx->endpoint_list, ep);
518 /* Re-get the string as we may have set a port */
519 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
521 if (use_single_process) {
522 ep_process_string = "single process required";
524 ep_process_string = "multi process compatible";
527 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
528 iface->name, ep_string, ep_process_string);
529 TALLOC_FREE(ep_string);
534 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
535 DATA_BLOB *session_key)
537 if (auth->session_info == NULL) {
538 return NT_STATUS_NO_USER_SESSION_KEY;
541 if (auth->session_info->session_key.length == 0) {
542 return NT_STATUS_NO_USER_SESSION_KEY;
545 *session_key = auth->session_info->session_key;
549 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
550 DATA_BLOB *session_key)
552 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
553 return NT_STATUS_NO_USER_SESSION_KEY;
556 return dcesrv_session_info_session_key(auth, session_key);
559 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
560 DATA_BLOB *session_key)
562 return dcerpc_generic_session_key(session_key);
566 * Fetch the authentication session key if available.
568 * This is the key generated by a gensec authentication.
571 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
572 DATA_BLOB *session_key)
574 struct dcesrv_auth *auth = call->auth_state;
575 SMB_ASSERT(auth->auth_finished);
576 return dcesrv_session_info_session_key(auth, session_key);
580 * Fetch the transport session key if available.
581 * Typically this is the SMB session key
582 * or a fixed key for local transports.
584 * The key is always truncated to 16 bytes.
586 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
587 DATA_BLOB *session_key)
589 struct dcesrv_auth *auth = call->auth_state;
592 SMB_ASSERT(auth->auth_finished);
594 if (auth->session_key_fn == NULL) {
595 return NT_STATUS_NO_USER_SESSION_KEY;
598 status = auth->session_key_fn(auth, session_key);
599 if (!NT_STATUS_IS_OK(status)) {
603 session_key->length = MIN(session_key->length, 16);
608 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
610 const struct dcesrv_endpoint *ep = conn->endpoint;
611 enum dcerpc_transport_t transport =
612 dcerpc_binding_get_transport(ep->ep_description);
613 struct dcesrv_auth *auth = NULL;
615 auth = talloc_zero(conn, struct dcesrv_auth);
622 auth->session_key_fn = dcesrv_remote_session_key;
625 case NCACN_UNIX_STREAM:
626 auth->session_key_fn = dcesrv_local_fixed_session_key;
630 * All other's get a NULL pointer, which
631 * results in NT_STATUS_NO_USER_SESSION_KEY
640 connect to a dcerpc endpoint
642 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
644 const struct dcesrv_endpoint *ep,
645 struct auth_session_info *session_info,
646 struct tevent_context *event_ctx,
647 uint32_t state_flags,
648 struct dcesrv_connection **_p)
650 struct dcesrv_auth *auth = NULL;
651 struct dcesrv_connection *p;
654 return NT_STATUS_ACCESS_DENIED;
657 p = talloc_zero(mem_ctx, struct dcesrv_connection);
658 NT_STATUS_HAVE_NO_MEMORY(p);
660 p->dce_ctx = dce_ctx;
662 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
663 p->event_ctx = event_ctx;
664 p->state_flags = state_flags;
665 p->allow_bind = true;
666 p->max_recv_frag = 5840;
667 p->max_xmit_frag = 5840;
668 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
670 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
675 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
681 auth = dcesrv_auth_create(p);
684 return NT_STATUS_NO_MEMORY;
687 auth->session_info = talloc_reference(auth, session_info);
688 if (auth->session_info == NULL) {
690 return NT_STATUS_NO_MEMORY;
693 p->default_auth_state = auth;
696 * For now we only support NDR32.
698 p->preferred_transfer = &ndr_transfer_syntax_ndr;
705 move a call from an existing linked list to the specified list. This
706 prevents bugs where we forget to remove the call from a previous
709 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
710 enum dcesrv_call_list list)
712 switch (call->list) {
713 case DCESRV_LIST_NONE:
715 case DCESRV_LIST_CALL_LIST:
716 DLIST_REMOVE(call->conn->call_list, call);
718 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
719 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
721 case DCESRV_LIST_PENDING_CALL_LIST:
722 DLIST_REMOVE(call->conn->pending_call_list, call);
727 case DCESRV_LIST_NONE:
729 case DCESRV_LIST_CALL_LIST:
730 DLIST_ADD_END(call->conn->call_list, call);
732 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
733 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
735 case DCESRV_LIST_PENDING_CALL_LIST:
736 DLIST_ADD_END(call->conn->pending_call_list, call);
741 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
744 struct dcesrv_auth *a = NULL;
746 if (call->conn->terminate != NULL) {
750 call->conn->allow_bind = false;
751 call->conn->allow_alter = false;
753 call->conn->default_auth_state->auth_invalid = true;
755 for (a = call->conn->auth_states; a != NULL; a = a->next) {
756 a->auth_invalid = true;
759 call->terminate_reason = talloc_strdup(call, reason);
760 if (call->terminate_reason == NULL) {
761 call->terminate_reason = __location__;
766 return a dcerpc bind_nak
768 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
770 struct ncacn_packet pkt;
771 struct dcerpc_bind_nak_version version;
772 struct data_blob_list_item *rep;
774 static const uint8_t _pad[3] = { 0, };
777 * We add the call to the pending_call_list
778 * in order to defer the termination.
780 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
782 /* setup a bind_nak */
783 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
785 pkt.call_id = call->pkt.call_id;
786 pkt.ptype = DCERPC_PKT_BIND_NAK;
787 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
788 pkt.u.bind_nak.reject_reason = reason;
789 version.rpc_vers = 5;
790 version.rpc_vers_minor = 0;
791 pkt.u.bind_nak.num_versions = 1;
792 pkt.u.bind_nak.versions = &version;
793 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
795 rep = talloc_zero(call, struct data_blob_list_item);
797 return NT_STATUS_NO_MEMORY;
800 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
801 if (!NT_STATUS_IS_OK(status)) {
805 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
807 DLIST_ADD_END(call->replies, rep);
808 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
810 if (call->conn->call_list && call->conn->call_list->replies) {
811 if (call->conn->transport.report_output_data) {
812 call->conn->transport.report_output_data(call->conn);
819 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
823 * We add the call to the pending_call_list
824 * in order to defer the termination.
826 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
828 return dcesrv_fault_with_flags(call, fault_code,
829 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
832 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
834 DLIST_REMOVE(c->conn->contexts, c);
836 if (c->iface && c->iface->unbind) {
837 c->iface->unbind(c, c->iface);
844 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
846 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
847 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
848 enum dcerpc_transport_t transport =
849 dcerpc_binding_get_transport(endpoint->ep_description);
850 struct dcesrv_connection_context *context = dce_call->context;
851 const struct dcesrv_interface *iface = context->iface;
853 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
855 if (transport == NCALRPC) {
856 context->allow_connect = true;
861 * allow overwrite per interface
862 * allow dcerpc auth level connect:<interface>
864 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
865 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
866 "allow dcerpc auth level connect",
868 context->allow_connect);
871 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
872 const struct dcesrv_interface *iface)
875 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
876 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
878 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
882 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
883 const struct dcesrv_interface *iface)
885 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
889 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
890 const struct dcesrv_interface *iface)
892 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
893 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
894 enum dcerpc_transport_t transport =
895 dcerpc_binding_get_transport(endpoint->ep_description);
897 if (transport == NCALRPC) {
898 context->allow_connect = true;
903 * allow overwrite per interface
904 * allow dcerpc auth level connect:<interface>
906 context->allow_connect = false;
907 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
908 "allow dcerpc auth level connect",
910 context->allow_connect);
914 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
915 const struct dcesrv_interface *iface)
917 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
918 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
919 enum dcerpc_transport_t transport =
920 dcerpc_binding_get_transport(endpoint->ep_description);
922 if (transport == NCALRPC) {
923 context->allow_connect = true;
928 * allow overwrite per interface
929 * allow dcerpc auth level connect:<interface>
931 context->allow_connect = true;
932 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
933 "allow dcerpc auth level connect",
935 context->allow_connect);
939 struct dcesrv_conn_auth_wait_context {
940 struct tevent_req *req;
945 struct dcesrv_conn_auth_wait_state {
949 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
950 struct tevent_context *ev,
953 struct dcesrv_conn_auth_wait_context *auth_wait =
954 talloc_get_type_abort(private_data,
955 struct dcesrv_conn_auth_wait_context);
956 struct tevent_req *req = NULL;
957 struct dcesrv_conn_auth_wait_state *state = NULL;
959 req = tevent_req_create(mem_ctx, &state,
960 struct dcesrv_conn_auth_wait_state);
964 auth_wait->req = req;
966 tevent_req_defer_callback(req, ev);
968 if (!auth_wait->done) {
972 if (tevent_req_nterror(req, auth_wait->status)) {
973 return tevent_req_post(req, ev);
976 tevent_req_done(req);
977 return tevent_req_post(req, ev);
980 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
982 return tevent_req_simple_recv_ntstatus(req);
985 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
987 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
989 if (conn->wait_send != NULL) {
990 return NT_STATUS_INTERNAL_ERROR;
993 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
994 if (auth_wait == NULL) {
995 return NT_STATUS_NO_MEMORY;
998 conn->wait_private = auth_wait;
999 conn->wait_send = dcesrv_conn_auth_wait_send;
1000 conn->wait_recv = dcesrv_conn_auth_wait_recv;
1001 return NT_STATUS_OK;
1004 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
1007 struct dcesrv_conn_auth_wait_context *auth_wait =
1008 talloc_get_type_abort(conn->wait_private,
1009 struct dcesrv_conn_auth_wait_context);
1011 auth_wait->done = true;
1012 auth_wait->status = status;
1014 if (auth_wait->req == NULL) {
1018 if (tevent_req_nterror(auth_wait->req, status)) {
1022 tevent_req_done(auth_wait->req);
1025 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
1027 static void dcesrv_bind_done(struct tevent_req *subreq);
1030 handle a bind request
1032 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
1034 struct dcesrv_connection *conn = call->conn;
1035 struct ncacn_packet *pkt = &call->ack_pkt;
1037 uint32_t extra_flags = 0;
1038 uint16_t max_req = 0;
1039 uint16_t max_rep = 0;
1040 struct dcerpc_binding *ep_2nd_description = NULL;
1041 const char *endpoint = NULL;
1042 struct dcesrv_auth *auth = call->auth_state;
1043 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1044 struct dcerpc_ack_ctx *ack_features = NULL;
1045 struct tevent_req *subreq = NULL;
1048 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1050 call->pkt.u.bind.auth_info.length,
1051 0, /* required flags */
1052 DCERPC_PFC_FLAG_FIRST |
1053 DCERPC_PFC_FLAG_LAST |
1054 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1055 0x08 | /* this is not defined, but should be ignored */
1056 DCERPC_PFC_FLAG_CONC_MPX |
1057 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1058 DCERPC_PFC_FLAG_MAYBE |
1059 DCERPC_PFC_FLAG_OBJECT_UUID);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 return dcesrv_bind_nak(call,
1062 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
1065 /* max_recv_frag and max_xmit_frag result always in the same value! */
1066 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
1067 call->pkt.u.bind.max_recv_frag);
1069 * The values are between 2048 and 5840 tested against Windows 2012R2
1070 * via ncacn_ip_tcp on port 135.
1072 max_req = MAX(2048, max_req);
1073 max_rep = MIN(max_req, call->conn->max_recv_frag);
1074 /* They are truncated to an 8 byte boundary. */
1077 /* max_recv_frag and max_xmit_frag result always in the same value! */
1078 call->conn->max_recv_frag = max_rep;
1079 call->conn->max_xmit_frag = max_rep;
1081 status = call->conn->dce_ctx->callbacks.assoc_group.find(call);
1082 if (!NT_STATUS_IS_OK(status)) {
1083 DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
1084 call->pkt.u.bind.assoc_group_id, nt_errstr(status));
1085 return dcesrv_bind_nak(call, 0);
1088 if (call->pkt.u.bind.num_contexts < 1) {
1089 return dcesrv_bind_nak(call, 0);
1092 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1093 call->pkt.u.bind.num_contexts);
1094 if (ack_ctx_list == NULL) {
1095 return dcesrv_bind_nak(call, 0);
1099 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1100 * dcesrv_check_or_create_context()) and do some protocol validation
1101 * and set sane defaults.
1103 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1104 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1105 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1106 bool is_feature = false;
1107 uint64_t features = 0;
1109 if (c->num_transfer_syntaxes == 0) {
1110 return dcesrv_bind_nak(call, 0);
1113 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1114 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1117 * It's only treated as bind time feature request, if the first
1118 * transfer_syntax matches, all others are ignored.
1120 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1126 if (ack_features != NULL) {
1128 * Only one bind time feature context is allowed.
1130 return dcesrv_bind_nak(call, 0);
1134 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1135 a->reason.negotiate = 0;
1136 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1137 if (call->conn->max_auth_states != 0) {
1138 a->reason.negotiate |=
1139 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1142 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1143 a->reason.negotiate |=
1144 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1147 call->conn->assoc_group->bind_time_features = a->reason.negotiate;
1151 * Try to negotiate one new presentation context.
1153 * Deep in here we locate the iface (by uuid) that the client
1154 * requested, from the list of interfaces on the
1155 * call->conn->endpoint, and call iface->bind() on that iface.
1157 * call->conn was set up at the accept() of the socket, and
1158 * call->conn->endpoint has a list of interfaces restricted to
1159 * this port or pipe.
1161 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1162 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1163 return dcesrv_bind_nak(call, 0);
1165 if (!NT_STATUS_IS_OK(status)) {
1170 * At this point we still don't know which interface (eg
1171 * netlogon, lsa, drsuapi) the caller requested in this bind!
1172 * The most recently added context is available as the first
1173 * element in the linked list at call->conn->contexts, that is
1174 * call->conn->contexts->iface, but they may not have
1175 * requested one at all!
1178 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1179 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1180 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1181 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1184 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1185 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1189 * After finding the interface and setting up the NDR
1190 * transport negotiation etc, handle any authentication that
1191 * is being requested.
1193 if (!dcesrv_auth_bind(call)) {
1195 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1197 * With DCERPC_AUTH_LEVEL_NONE, we get the
1198 * reject_reason in auth->auth_context_id.
1200 return dcesrv_bind_nak(call, auth->auth_context_id);
1204 * This must a be a temporary failure e.g. talloc or invalid
1205 * configuration, e.g. no machine account.
1207 return dcesrv_bind_nak(call,
1208 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1211 /* setup a bind_ack */
1212 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1213 pkt->auth_length = 0;
1214 pkt->call_id = call->pkt.call_id;
1215 pkt->ptype = DCERPC_PKT_BIND_ACK;
1216 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1217 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1218 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1219 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1221 ep_2nd_description = call->conn->endpoint->ep_2nd_description;
1222 if (ep_2nd_description == NULL) {
1223 ep_2nd_description = call->conn->endpoint->ep_description;
1226 endpoint = dcerpc_binding_get_string_option(
1229 if (endpoint == NULL) {
1233 pkt->u.bind_ack.secondary_address = endpoint;
1234 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1235 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1236 pkt->u.bind_ack.auth_info = data_blob_null;
1238 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 return dcesrv_bind_nak(call, 0);
1243 if (auth->auth_finished) {
1244 return dcesrv_auth_reply(call);
1247 subreq = gensec_update_send(call, call->event_ctx,
1248 auth->gensec_security,
1249 call->in_auth_info.credentials);
1250 if (subreq == NULL) {
1251 return NT_STATUS_NO_MEMORY;
1253 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1255 return dcesrv_conn_auth_wait_setup(conn);
1258 static void dcesrv_bind_done(struct tevent_req *subreq)
1260 struct dcesrv_call_state *call =
1261 tevent_req_callback_data(subreq,
1262 struct dcesrv_call_state);
1263 struct dcesrv_connection *conn = call->conn;
1266 status = gensec_update_recv(subreq, call,
1267 &call->out_auth_info->credentials);
1268 TALLOC_FREE(subreq);
1270 status = dcesrv_auth_complete(call, status);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 status = dcesrv_bind_nak(call, 0);
1273 dcesrv_conn_auth_wait_finished(conn, status);
1277 status = dcesrv_auth_reply(call);
1278 dcesrv_conn_auth_wait_finished(conn, status);
1282 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1284 struct ncacn_packet *pkt = &call->ack_pkt;
1285 struct data_blob_list_item *rep = NULL;
1288 rep = talloc_zero(call, struct data_blob_list_item);
1290 return NT_STATUS_NO_MEMORY;
1293 status = dcerpc_ncacn_push_auth(&rep->blob,
1296 call->out_auth_info);
1297 if (!NT_STATUS_IS_OK(status)) {
1301 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1303 DLIST_ADD_END(call->replies, rep);
1304 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1306 if (call->conn->call_list && call->conn->call_list->replies) {
1307 if (call->conn->transport.report_output_data) {
1308 call->conn->transport.report_output_data(call->conn);
1312 return NT_STATUS_OK;
1316 static void dcesrv_auth3_done(struct tevent_req *subreq);
1319 handle a auth3 request
1321 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1323 struct dcesrv_connection *conn = call->conn;
1324 struct dcesrv_auth *auth = call->auth_state;
1325 struct tevent_req *subreq = NULL;
1328 if (!auth->auth_started) {
1329 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1332 if (auth->auth_finished) {
1333 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1336 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1338 call->pkt.u.auth3.auth_info.length,
1339 0, /* required flags */
1340 DCERPC_PFC_FLAG_FIRST |
1341 DCERPC_PFC_FLAG_LAST |
1342 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1343 0x08 | /* this is not defined, but should be ignored */
1344 DCERPC_PFC_FLAG_CONC_MPX |
1345 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1346 DCERPC_PFC_FLAG_MAYBE |
1347 DCERPC_PFC_FLAG_OBJECT_UUID);
1348 if (!NT_STATUS_IS_OK(status)) {
1349 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1352 /* handle the auth3 in the auth code */
1353 if (!dcesrv_auth_prepare_auth3(call)) {
1355 * we don't send a reply to a auth3 request,
1356 * except by a fault.
1358 * In anycase we mark the connection as
1361 auth->auth_invalid = true;
1362 if (call->fault_code != 0) {
1363 return dcesrv_fault_disconnect(call, call->fault_code);
1366 return NT_STATUS_OK;
1369 subreq = gensec_update_send(call, call->event_ctx,
1370 auth->gensec_security,
1371 call->in_auth_info.credentials);
1372 if (subreq == NULL) {
1373 return NT_STATUS_NO_MEMORY;
1375 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1377 return dcesrv_conn_auth_wait_setup(conn);
1380 static void dcesrv_auth3_done(struct tevent_req *subreq)
1382 struct dcesrv_call_state *call =
1383 tevent_req_callback_data(subreq,
1384 struct dcesrv_call_state);
1385 struct dcesrv_connection *conn = call->conn;
1386 struct dcesrv_auth *auth = call->auth_state;
1389 status = gensec_update_recv(subreq, call,
1390 &call->out_auth_info->credentials);
1391 TALLOC_FREE(subreq);
1393 status = dcesrv_auth_complete(call, status);
1394 if (!NT_STATUS_IS_OK(status)) {
1396 * we don't send a reply to a auth3 request,
1397 * except by a fault.
1399 * In anycase we mark the connection as
1402 auth->auth_invalid = true;
1403 if (call->fault_code != 0) {
1404 status = dcesrv_fault_disconnect(call, call->fault_code);
1405 dcesrv_conn_auth_wait_finished(conn, status);
1409 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1414 * we don't send a reply to a auth3 request.
1417 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1422 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1423 const struct dcerpc_bind *b,
1424 const struct dcerpc_ctx_list *ctx,
1425 struct dcerpc_ack_ctx *ack,
1427 const struct ndr_syntax_id *supported_transfer)
1429 uint32_t if_version;
1430 struct dcesrv_connection_context *context;
1431 const struct dcesrv_interface *iface;
1434 const struct ndr_syntax_id *selected_transfer = NULL;
1439 return NT_STATUS_INTERNAL_ERROR;
1442 return NT_STATUS_INTERNAL_ERROR;
1444 if (ctx->num_transfer_syntaxes < 1) {
1445 return NT_STATUS_INTERNAL_ERROR;
1448 return NT_STATUS_INTERNAL_ERROR;
1450 if (supported_transfer == NULL) {
1451 return NT_STATUS_INTERNAL_ERROR;
1454 switch (ack->result) {
1455 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1456 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1458 * We is already completed.
1460 return NT_STATUS_OK;
1465 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1466 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1468 if_version = ctx->abstract_syntax.if_version;
1469 uuid = ctx->abstract_syntax.uuid;
1471 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1472 if (iface == NULL) {
1473 char *uuid_str = GUID_string(call, &uuid);
1474 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1475 talloc_free(uuid_str);
1477 * We report this only via ack->result
1479 return NT_STATUS_OK;
1482 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1483 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1485 if (validate_only) {
1487 * We report this only via ack->result
1489 return NT_STATUS_OK;
1492 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1494 * we only do NDR encoded dcerpc for now.
1496 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1497 supported_transfer);
1499 selected_transfer = supported_transfer;
1504 context = dcesrv_find_context(call->conn, ctx->context_id);
1505 if (context != NULL) {
1506 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1507 &ctx->abstract_syntax);
1509 return NT_STATUS_RPC_PROTOCOL_ERROR;
1512 if (selected_transfer != NULL) {
1513 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1516 return NT_STATUS_RPC_PROTOCOL_ERROR;
1519 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1520 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1521 ack->syntax = context->transfer_syntax;
1525 * We report this only via ack->result
1527 return NT_STATUS_OK;
1530 if (selected_transfer == NULL) {
1532 * We report this only via ack->result
1534 return NT_STATUS_OK;
1537 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1538 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1540 /* add this context to the list of available context_ids */
1541 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1542 if (context == NULL) {
1543 return NT_STATUS_NO_MEMORY;
1545 context->conn = call->conn;
1546 context->context_id = ctx->context_id;
1547 context->iface = iface;
1548 context->transfer_syntax = *selected_transfer;
1549 DLIST_ADD(call->conn->contexts, context);
1550 call->context = context;
1551 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1553 dcesrv_prepare_context_auth(call);
1556 * Multiplex is supported by default
1558 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1560 status = iface->bind(context, iface);
1561 call->context = NULL;
1562 if (!NT_STATUS_IS_OK(status)) {
1563 /* we don't want to trigger the iface->unbind() hook */
1564 context->iface = NULL;
1565 talloc_free(context);
1567 * We report this only via ack->result
1569 return NT_STATUS_OK;
1572 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1573 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1574 ack->syntax = context->transfer_syntax;
1575 return NT_STATUS_OK;
1578 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1579 const struct dcerpc_bind *b,
1580 struct dcerpc_ack_ctx *ack_ctx_list)
1584 bool validate_only = false;
1585 bool preferred_ndr32;
1588 * Try to negotiate one new presentation context,
1589 * using our preferred transfer syntax.
1591 for (i = 0; i < b->num_contexts; i++) {
1592 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1593 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1595 status = dcesrv_check_or_create_context(call, b, c, a,
1597 call->conn->preferred_transfer);
1598 if (!NT_STATUS_IS_OK(status)) {
1602 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1604 * We managed to negotiate one context.
1608 validate_only = true;
1612 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1613 call->conn->preferred_transfer);
1614 if (preferred_ndr32) {
1618 return NT_STATUS_OK;
1622 * Try to negotiate one new presentation context,
1623 * using NDR 32 as fallback.
1625 for (i = 0; i < b->num_contexts; i++) {
1626 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1627 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1629 status = dcesrv_check_or_create_context(call, b, c, a,
1631 &ndr_transfer_syntax_ndr);
1632 if (!NT_STATUS_IS_OK(status)) {
1636 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1638 * We managed to negotiate one context.
1642 validate_only = true;
1646 return NT_STATUS_OK;
1649 static void dcesrv_alter_done(struct tevent_req *subreq);
1652 handle a alter context request
1654 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1656 struct dcesrv_connection *conn = call->conn;
1658 bool auth_ok = false;
1659 struct ncacn_packet *pkt = &call->ack_pkt;
1660 uint32_t extra_flags = 0;
1661 struct dcesrv_auth *auth = call->auth_state;
1662 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1663 struct tevent_req *subreq = NULL;
1666 if (!call->conn->allow_alter) {
1667 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1670 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1672 call->pkt.u.alter.auth_info.length,
1673 0, /* required flags */
1674 DCERPC_PFC_FLAG_FIRST |
1675 DCERPC_PFC_FLAG_LAST |
1676 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1677 0x08 | /* this is not defined, but should be ignored */
1678 DCERPC_PFC_FLAG_CONC_MPX |
1679 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1680 DCERPC_PFC_FLAG_MAYBE |
1681 DCERPC_PFC_FLAG_OBJECT_UUID);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1686 auth_ok = dcesrv_auth_alter(call);
1688 if (call->fault_code != 0) {
1689 return dcesrv_fault_disconnect(call, call->fault_code);
1693 if (call->pkt.u.alter.num_contexts < 1) {
1694 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1697 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1698 call->pkt.u.alter.num_contexts);
1699 if (ack_ctx_list == NULL) {
1700 return NT_STATUS_NO_MEMORY;
1704 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1705 * dcesrv_check_or_create_context()) and do some protocol validation
1706 * and set sane defaults.
1708 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1709 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1710 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1712 if (c->num_transfer_syntaxes == 0) {
1713 return dcesrv_fault_disconnect(call,
1714 DCERPC_NCA_S_PROTO_ERROR);
1717 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1718 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1722 * Try to negotiate one new presentation context.
1724 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1725 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1726 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1728 if (!NT_STATUS_IS_OK(status)) {
1732 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1733 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1734 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1735 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1738 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1739 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1742 /* handle any authentication that is being requested */
1744 if (call->in_auth_info.auth_type != auth->auth_type) {
1745 return dcesrv_fault_disconnect(call,
1746 DCERPC_FAULT_SEC_PKG_ERROR);
1748 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1751 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1752 pkt->auth_length = 0;
1753 pkt->call_id = call->pkt.call_id;
1754 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1755 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1756 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1757 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1758 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1759 pkt->u.alter_resp.secondary_address = "";
1760 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1761 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1762 pkt->u.alter_resp.auth_info = data_blob_null;
1764 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1765 if (!NT_STATUS_IS_OK(status)) {
1766 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1769 if (auth->auth_finished) {
1770 return dcesrv_auth_reply(call);
1773 subreq = gensec_update_send(call, call->event_ctx,
1774 auth->gensec_security,
1775 call->in_auth_info.credentials);
1776 if (subreq == NULL) {
1777 return NT_STATUS_NO_MEMORY;
1779 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1781 return dcesrv_conn_auth_wait_setup(conn);
1784 static void dcesrv_alter_done(struct tevent_req *subreq)
1786 struct dcesrv_call_state *call =
1787 tevent_req_callback_data(subreq,
1788 struct dcesrv_call_state);
1789 struct dcesrv_connection *conn = call->conn;
1792 status = gensec_update_recv(subreq, call,
1793 &call->out_auth_info->credentials);
1794 TALLOC_FREE(subreq);
1796 status = dcesrv_auth_complete(call, status);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1799 dcesrv_conn_auth_wait_finished(conn, status);
1803 status = dcesrv_auth_reply(call);
1804 dcesrv_conn_auth_wait_finished(conn, status);
1809 possibly save the call for inspection with ndrdump
1811 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1815 const char *dump_dir;
1816 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1820 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1822 call->context->iface->name,
1823 call->pkt.u.request.opnum,
1825 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1826 DEBUG(0,("RPC SAVED %s\n", fname));
1832 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1834 TALLOC_CTX *frame = talloc_stackframe();
1835 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1836 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1837 const struct dcerpc_sec_vt_pcontext pcontext = {
1838 .abstract_syntax = call->context->iface->syntax_id,
1839 .transfer_syntax = call->context->transfer_syntax,
1841 const struct dcerpc_sec_vt_header2 header2 =
1842 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1843 enum ndr_err_code ndr_err;
1844 struct dcerpc_sec_verification_trailer *vt = NULL;
1845 NTSTATUS status = NT_STATUS_OK;
1848 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1850 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1852 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1853 status = ndr_map_error2ntstatus(ndr_err);
1857 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1858 &pcontext, &header2);
1860 status = NT_STATUS_ACCESS_DENIED;
1869 handle a dcerpc request packet
1871 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1873 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1874 struct dcesrv_auth *auth = call->auth_state;
1875 enum dcerpc_transport_t transport =
1876 dcerpc_binding_get_transport(endpoint->ep_description);
1877 struct ndr_pull *pull;
1880 if (!auth->auth_finished) {
1881 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1884 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1885 if (auth->gensec_security != NULL &&
1886 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1887 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1890 if (call->context == NULL) {
1891 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1892 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1895 switch (auth->auth_level) {
1896 case DCERPC_AUTH_LEVEL_NONE:
1897 case DCERPC_AUTH_LEVEL_PACKET:
1898 case DCERPC_AUTH_LEVEL_INTEGRITY:
1899 case DCERPC_AUTH_LEVEL_PRIVACY:
1902 if (!call->context->allow_connect) {
1905 addr = tsocket_address_string(call->conn->remote_address,
1908 DEBUG(2, ("%s: restrict auth_level_connect access "
1909 "to [%s] with auth[type=0x%x,level=0x%x] "
1910 "on [%s] from [%s]\n",
1911 __func__, call->context->iface->name,
1914 derpc_transport_string_by_transport(transport),
1916 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1921 if (auth->auth_level < call->context->min_auth_level) {
1924 addr = tsocket_address_string(call->conn->remote_address, call);
1926 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1927 "to [%s] with auth[type=0x%x,level=0x%x] "
1928 "on [%s] from [%s]\n",
1930 call->context->min_auth_level,
1931 call->context->iface->name,
1934 derpc_transport_string_by_transport(transport),
1936 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1939 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1940 NT_STATUS_HAVE_NO_MEMORY(pull);
1942 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1944 call->ndr_pull = pull;
1946 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1947 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1950 status = dcesrv_check_verification_trailer(call);
1951 if (!NT_STATUS_IS_OK(status)) {
1952 uint32_t faultcode = DCERPC_FAULT_OTHER;
1953 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1954 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1956 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1957 nt_errstr(status)));
1958 return dcesrv_fault(call, faultcode);
1961 /* unravel the NDR for the packet */
1962 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1963 if (!NT_STATUS_IS_OK(status)) {
1964 uint8_t extra_flags = 0;
1965 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1966 /* we got an unknown call */
1967 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1968 call->pkt.u.request.opnum,
1969 call->context->iface->name));
1970 dcesrv_save_call(call, "unknown");
1971 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1973 dcesrv_save_call(call, "pullfail");
1975 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1978 if (pull->offset != pull->data_size) {
1979 dcesrv_save_call(call, "extrabytes");
1980 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1981 pull->data_size - pull->offset));
1984 /* call the dispatch function */
1985 status = call->context->iface->dispatch(call, call, call->r);
1986 if (!NT_STATUS_IS_OK(status)) {
1987 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1988 call->context->iface->name,
1989 call->pkt.u.request.opnum,
1990 dcerpc_errstr(pull, call->fault_code)));
1991 return dcesrv_fault(call, call->fault_code);
1994 /* add the call to the pending list */
1995 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1997 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1998 return NT_STATUS_OK;
2001 return dcesrv_reply(call);
2006 remove the call from the right list when freed
2008 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
2010 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2014 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
2016 return conn->local_address;
2019 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
2021 return conn->remote_address;
2025 process some input to a dcerpc endpoint server.
2027 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2028 struct ncacn_packet *pkt,
2032 struct dcesrv_call_state *call;
2033 struct dcesrv_call_state *existing = NULL;
2034 size_t num_auth_ctx = 0;
2035 enum dcerpc_AuthType auth_type = 0;
2036 enum dcerpc_AuthLevel auth_level = 0;
2037 uint32_t auth_context_id = 0;
2039 call = talloc_zero(dce_conn, struct dcesrv_call_state);
2041 data_blob_free(&blob);
2043 return NT_STATUS_NO_MEMORY;
2045 call->conn = dce_conn;
2046 call->event_ctx = dce_conn->event_ctx;
2047 call->state_flags = call->conn->state_flags;
2048 call->time = timeval_current();
2049 call->list = DCESRV_LIST_NONE;
2051 talloc_steal(call, pkt);
2052 talloc_steal(call, blob.data);
2055 if (dce_conn->max_auth_states == 0) {
2056 call->auth_state = dce_conn->default_auth_state;
2057 } else if (call->pkt.auth_length == 0) {
2058 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2059 dce_conn->default_auth_level_connect != NULL)
2061 call->auth_state = dce_conn->default_auth_level_connect;
2063 call->auth_state = dce_conn->default_auth_state;
2067 if (call->auth_state == NULL) {
2068 struct dcesrv_auth *a = NULL;
2070 auth_type = dcerpc_get_auth_type(&blob);
2071 auth_level = dcerpc_get_auth_level(&blob);
2072 auth_context_id = dcerpc_get_auth_context_id(&blob);
2074 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2075 dce_conn->default_auth_level_connect = NULL;
2076 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
2077 dce_conn->got_explicit_auth_level_connect = true;
2081 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2084 if (a->auth_type != auth_type) {
2087 if (a->auth_finished && a->auth_level != auth_level) {
2090 if (a->auth_context_id != auth_context_id) {
2094 DLIST_PROMOTE(dce_conn->auth_states, a);
2095 call->auth_state = a;
2100 if (call->auth_state == NULL) {
2101 struct dcesrv_auth *a = NULL;
2103 if (num_auth_ctx >= dce_conn->max_auth_states) {
2104 return dcesrv_fault_disconnect(call,
2105 DCERPC_NCA_S_PROTO_ERROR);
2108 a = dcesrv_auth_create(dce_conn);
2111 return NT_STATUS_NO_MEMORY;
2113 DLIST_ADD(dce_conn->auth_states, a);
2114 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2116 * This can never be valid.
2118 a->auth_invalid = true;
2120 call->auth_state = a;
2123 talloc_set_destructor(call, dcesrv_call_dequeue);
2125 if (call->conn->allow_bind) {
2127 * Only one bind is possible per connection
2129 call->conn->allow_bind = false;
2130 return dcesrv_bind(call);
2133 /* we have to check the signing here, before combining the
2135 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2136 dcesrv_default_auth_state_prepare_request(call);
2138 if (call->auth_state->auth_started &&
2139 !call->auth_state->auth_finished) {
2140 return dcesrv_fault_disconnect(call,
2141 DCERPC_NCA_S_PROTO_ERROR);
2144 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2146 call->pkt.u.request.stub_and_verifier.length,
2147 0, /* required_flags */
2148 DCERPC_PFC_FLAG_FIRST |
2149 DCERPC_PFC_FLAG_LAST |
2150 DCERPC_PFC_FLAG_PENDING_CANCEL |
2151 0x08 | /* this is not defined, but should be ignored */
2152 DCERPC_PFC_FLAG_CONC_MPX |
2153 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2154 DCERPC_PFC_FLAG_MAYBE |
2155 DCERPC_PFC_FLAG_OBJECT_UUID);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 return dcesrv_fault_disconnect(call,
2158 DCERPC_NCA_S_PROTO_ERROR);
2161 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2163 * We don't use dcesrv_fault_disconnect()
2164 * here, because we don't want to set
2165 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2167 * Note that we don't check against the negotiated
2168 * max_recv_frag, but a hard coded value.
2170 dcesrv_call_disconnect_after(call,
2171 "dcesrv_auth_request - frag_length too large");
2172 return dcesrv_fault(call,
2173 DCERPC_NCA_S_PROTO_ERROR);
2176 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2177 if (dce_conn->pending_call_list != NULL) {
2179 * concurrent requests are only allowed
2180 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2182 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2183 dcesrv_call_disconnect_after(call,
2184 "dcesrv_auth_request - "
2185 "existing pending call without CONN_MPX");
2186 return dcesrv_fault(call,
2187 DCERPC_NCA_S_PROTO_ERROR);
2190 /* only one request is possible in the fragmented list */
2191 if (dce_conn->incoming_fragmented_call_list != NULL) {
2192 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2194 * Without DCERPC_PFC_FLAG_CONC_MPX
2195 * we need to return the FAULT on the
2196 * already existing call.
2198 * This is important to get the
2199 * call_id and context_id right.
2202 call = dce_conn->incoming_fragmented_call_list;
2204 dcesrv_call_disconnect_after(call,
2205 "dcesrv_auth_request - "
2206 "existing fragmented call");
2207 return dcesrv_fault(call,
2208 DCERPC_NCA_S_PROTO_ERROR);
2210 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2211 return dcesrv_fault_disconnect(call,
2212 DCERPC_FAULT_NO_CALL_ACTIVE);
2214 call->context = dcesrv_find_context(call->conn,
2215 call->pkt.u.request.context_id);
2216 if (call->context == NULL) {
2217 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2218 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2221 const struct dcerpc_request *nr = &call->pkt.u.request;
2222 const struct dcerpc_request *er = NULL;
2225 existing = dcesrv_find_fragmented_call(dce_conn,
2227 if (existing == NULL) {
2228 dcesrv_call_disconnect_after(call,
2229 "dcesrv_auth_request - "
2230 "no existing fragmented call");
2231 return dcesrv_fault(call,
2232 DCERPC_NCA_S_PROTO_ERROR);
2234 er = &existing->pkt.u.request;
2236 if (call->pkt.ptype != existing->pkt.ptype) {
2237 /* trying to play silly buggers are we? */
2238 return dcesrv_fault_disconnect(existing,
2239 DCERPC_NCA_S_PROTO_ERROR);
2241 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2244 return dcesrv_fault_disconnect(existing,
2245 DCERPC_NCA_S_PROTO_ERROR);
2247 if (nr->context_id != er->context_id) {
2248 return dcesrv_fault_disconnect(existing,
2249 DCERPC_NCA_S_PROTO_ERROR);
2251 if (nr->opnum != er->opnum) {
2252 return dcesrv_fault_disconnect(existing,
2253 DCERPC_NCA_S_PROTO_ERROR);
2258 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2260 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2262 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2263 payload_offset += 16;
2266 ok = dcesrv_auth_pkt_pull(call, &blob,
2267 0, /* required_flags */
2268 DCERPC_PFC_FLAG_FIRST |
2269 DCERPC_PFC_FLAG_LAST |
2270 DCERPC_PFC_FLAG_PENDING_CANCEL |
2271 0x08 | /* this is not defined, but should be ignored */
2272 DCERPC_PFC_FLAG_CONC_MPX |
2273 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2274 DCERPC_PFC_FLAG_MAYBE |
2275 DCERPC_PFC_FLAG_OBJECT_UUID,
2277 &call->pkt.u.request.stub_and_verifier);
2280 * We don't use dcesrv_fault_disconnect()
2281 * here, because we don't want to set
2282 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2284 dcesrv_call_disconnect_after(call,
2285 "dcesrv_auth_request - failed");
2286 if (call->fault_code == 0) {
2287 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2289 return dcesrv_fault(call, call->fault_code);
2293 /* see if this is a continued packet */
2294 if (existing != NULL) {
2295 struct dcerpc_request *er = &existing->pkt.u.request;
2296 const struct dcerpc_request *nr = &call->pkt.u.request;
2302 * Up to 4 MByte are allowed by all fragments
2304 available = dce_conn->max_total_request_size;
2305 if (er->stub_and_verifier.length > available) {
2306 dcesrv_call_disconnect_after(existing,
2307 "dcesrv_auth_request - existing payload too large");
2308 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2310 available -= er->stub_and_verifier.length;
2311 if (nr->alloc_hint > available) {
2312 dcesrv_call_disconnect_after(existing,
2313 "dcesrv_auth_request - alloc hint too large");
2314 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2316 if (nr->stub_and_verifier.length > available) {
2317 dcesrv_call_disconnect_after(existing,
2318 "dcesrv_auth_request - new payload too large");
2319 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2321 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2322 /* allocate at least 1 byte */
2323 alloc_hint = MAX(alloc_hint, 1);
2324 alloc_size = er->stub_and_verifier.length +
2325 nr->stub_and_verifier.length;
2326 alloc_size = MAX(alloc_size, alloc_hint);
2328 er->stub_and_verifier.data =
2329 talloc_realloc(existing,
2330 er->stub_and_verifier.data,
2331 uint8_t, alloc_size);
2332 if (er->stub_and_verifier.data == NULL) {
2334 return dcesrv_fault_with_flags(existing,
2335 DCERPC_FAULT_OUT_OF_RESOURCES,
2336 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2338 memcpy(er->stub_and_verifier.data +
2339 er->stub_and_verifier.length,
2340 nr->stub_and_verifier.data,
2341 nr->stub_and_verifier.length);
2342 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2344 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2350 /* this may not be the last pdu in the chain - if its isn't then
2351 just put it on the incoming_fragmented_call_list and wait for the rest */
2352 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2353 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2355 * Up to 4 MByte are allowed by all fragments
2357 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2358 dcesrv_call_disconnect_after(call,
2359 "dcesrv_auth_request - initial alloc hint too large");
2360 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2362 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2363 return NT_STATUS_OK;
2366 /* This removes any fragments we may have had stashed away */
2367 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2369 switch (call->pkt.ptype) {
2370 case DCERPC_PKT_BIND:
2371 status = dcesrv_bind_nak(call,
2372 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2374 case DCERPC_PKT_AUTH3:
2375 status = dcesrv_auth3(call);
2377 case DCERPC_PKT_ALTER:
2378 status = dcesrv_alter(call);
2380 case DCERPC_PKT_REQUEST:
2381 status = dcesrv_request(call);
2383 case DCERPC_PKT_CO_CANCEL:
2384 case DCERPC_PKT_ORPHANED:
2386 * Window just ignores CO_CANCEL and ORPHANED,
2389 status = NT_STATUS_OK;
2392 case DCERPC_PKT_BIND_ACK:
2393 case DCERPC_PKT_BIND_NAK:
2394 case DCERPC_PKT_ALTER_RESP:
2395 case DCERPC_PKT_RESPONSE:
2396 case DCERPC_PKT_FAULT:
2397 case DCERPC_PKT_SHUTDOWN:
2399 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2403 /* if we are going to be sending a reply then add
2404 it to the list of pending calls. We add it to the end to keep the call
2405 list in the order we will answer */
2406 if (!NT_STATUS_IS_OK(status)) {
2413 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2414 struct loadparm_context *lp_ctx,
2415 const char **endpoint_servers,
2416 struct dcesrv_context_callbacks *cb,
2417 struct dcesrv_context **_dce_ctx)
2420 struct dcesrv_context *dce_ctx;
2423 if (!endpoint_servers) {
2424 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2425 return NT_STATUS_INTERNAL_ERROR;
2428 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2429 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2431 if (uid_wrapper_enabled()) {
2432 setenv("UID_WRAPPER_MYUID", "1", 1);
2434 dce_ctx->initial_euid = geteuid();
2435 if (uid_wrapper_enabled()) {
2436 unsetenv("UID_WRAPPER_MYUID");
2439 dce_ctx->endpoint_list = NULL;
2440 dce_ctx->lp_ctx = lp_ctx;
2441 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2442 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2443 dce_ctx->broken_connections = NULL;
2445 dce_ctx->callbacks = *cb;
2448 for (i=0;endpoint_servers[i];i++) {
2449 const struct dcesrv_endpoint_server *ep_server;
2451 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2453 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2454 return NT_STATUS_INTERNAL_ERROR;
2457 status = ep_server->init_server(dce_ctx, ep_server);
2458 if (!NT_STATUS_IS_OK(status)) {
2459 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2460 nt_errstr(status)));
2465 *_dce_ctx = dce_ctx;
2466 return NT_STATUS_OK;
2469 /* the list of currently registered DCERPC endpoint servers.
2471 static struct ep_server {
2472 struct dcesrv_endpoint_server *ep_server;
2473 } *ep_servers = NULL;
2474 static int num_ep_servers;
2477 register a DCERPC endpoint server.
2479 The 'name' can be later used by other backends to find the operations
2480 structure for this backend.
2483 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2486 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2487 /* its already registered! */
2488 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2490 return NT_STATUS_OBJECT_NAME_COLLISION;
2493 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2495 smb_panic("out of memory in dcerpc_register");
2498 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2499 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2503 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2506 return NT_STATUS_OK;
2510 return the operations structure for a named backend of the specified type
2512 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2516 for (i=0;i<num_ep_servers;i++) {
2517 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2518 return ep_servers[i].ep_server;
2525 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2527 static bool initialized;
2528 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2529 STATIC_dcerpc_server_MODULES_PROTO;
2530 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2531 init_module_fn *shared_init;
2538 shared_init = load_samba_modules(NULL, "dcerpc_server");
2540 run_init_functions(NULL, static_init);
2541 run_init_functions(NULL, shared_init);
2543 talloc_free(shared_init);
2547 return the DCERPC module version, and the size of some critical types
2548 This can be used by endpoint server modules to either detect compilation errors, or provide
2549 multiple implementations for different smbd compilation options in one module
2551 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2553 static const struct dcesrv_critical_sizes critical_sizes = {
2554 DCERPC_MODULE_VERSION,
2555 sizeof(struct dcesrv_context),
2556 sizeof(struct dcesrv_endpoint),
2557 sizeof(struct dcesrv_endpoint_server),
2558 sizeof(struct dcesrv_interface),
2559 sizeof(struct dcesrv_if_list),
2560 sizeof(struct dcesrv_connection),
2561 sizeof(struct dcesrv_call_state),
2562 sizeof(struct dcesrv_auth),
2563 sizeof(struct dcesrv_handle)
2566 return &critical_sizes;
2569 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2571 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2572 struct dcesrv_auth *a = NULL;
2574 dce_conn->wait_send = NULL;
2575 dce_conn->wait_recv = NULL;
2576 dce_conn->wait_private = NULL;
2578 dce_conn->allow_bind = false;
2579 dce_conn->allow_alter = false;
2581 dce_conn->default_auth_state->auth_invalid = true;
2583 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2584 a->auth_invalid = true;
2587 if (dce_conn->pending_call_list == NULL) {
2588 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2590 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2591 dce_conn->transport.terminate_connection(dce_conn,
2592 full_reason ? full_reason : reason);
2596 if (dce_conn->terminate != NULL) {
2600 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2602 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2603 if (dce_conn->terminate == NULL) {
2604 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2606 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2609 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2611 struct dcesrv_connection *cur, *next;
2613 next = dce_ctx->broken_connections;
2614 while (next != NULL) {
2618 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2619 struct dcesrv_connection_context *context_cur, *context_next;
2621 context_next = cur->contexts;
2622 while (context_next != NULL) {
2623 context_cur = context_next;
2624 context_next = context_cur->next;
2626 dcesrv_connection_context_destructor(context_cur);
2630 dcesrv_terminate_connection(cur, cur->terminate);
2634 /* We need this include to be able to compile on some plateforms
2635 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2637 * It has to be that deep because otherwise we have a conflict on
2638 * const struct dcesrv_interface declaration.
2639 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2640 * which conflict with the bind used before.
2642 #include "system/network.h"
2644 struct dcesrv_sock_reply_state {
2645 struct dcesrv_connection *dce_conn;
2646 struct dcesrv_call_state *call;
2650 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2651 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2653 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2655 struct dcesrv_call_state *call;
2657 call = dce_conn->call_list;
2658 if (!call || !call->replies) {
2662 while (call->replies) {
2663 struct data_blob_list_item *rep = call->replies;
2664 struct dcesrv_sock_reply_state *substate;
2665 struct tevent_req *subreq;
2667 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2669 dcesrv_terminate_connection(dce_conn, "no memory");
2673 substate->dce_conn = dce_conn;
2674 substate->call = NULL;
2676 DLIST_REMOVE(call->replies, rep);
2678 if (call->replies == NULL && call->terminate_reason == NULL) {
2679 substate->call = call;
2682 substate->iov.iov_base = (void *) rep->blob.data;
2683 substate->iov.iov_len = rep->blob.length;
2685 subreq = tstream_writev_queue_send(substate,
2686 dce_conn->event_ctx,
2688 dce_conn->send_queue,
2691 dcesrv_terminate_connection(dce_conn, "no memory");
2694 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2698 if (call->terminate_reason != NULL) {
2699 struct tevent_req *subreq;
2701 subreq = tevent_queue_wait_send(call,
2702 dce_conn->event_ctx,
2703 dce_conn->send_queue);
2705 dcesrv_terminate_connection(dce_conn, __location__);
2708 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2712 DLIST_REMOVE(call->conn->call_list, call);
2713 call->list = DCESRV_LIST_NONE;
2716 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2718 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2719 struct dcesrv_sock_reply_state);
2723 struct dcesrv_call_state *call = substate->call;
2725 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2726 TALLOC_FREE(subreq);
2728 status = map_nt_error_from_unix_common(sys_errno);
2729 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2733 talloc_free(substate);
2739 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2741 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2743 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2744 struct dcesrv_call_state);
2748 /* make sure we stop send queue before removing subreq */
2749 tevent_queue_stop(call->conn->send_queue);
2751 ok = tevent_queue_wait_recv(subreq);
2752 TALLOC_FREE(subreq);
2754 dcesrv_terminate_connection(call->conn, __location__);
2758 /* disconnect after 200 usecs */
2759 tv = timeval_current_ofs_usec(200);
2760 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2761 if (subreq == NULL) {
2762 dcesrv_terminate_connection(call->conn, __location__);
2765 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2769 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2771 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2772 struct dcesrv_call_state);
2775 ok = tevent_wakeup_recv(subreq);
2776 TALLOC_FREE(subreq);
2778 dcesrv_terminate_connection(call->conn, __location__);
2782 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2785 struct dcesrv_socket_context {
2786 const struct dcesrv_endpoint *endpoint;
2787 struct dcesrv_context *dcesrv_ctx;
2790 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2793 struct dcesrv_socket_context *dcesrv_sock =
2794 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2795 enum dcerpc_transport_t transport =
2796 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2797 struct dcesrv_connection *dcesrv_conn = NULL;
2799 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2801 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2803 if (!srv_conn->session_info) {
2804 status = auth_anonymous_session_info(srv_conn,
2806 &srv_conn->session_info);
2807 if (!NT_STATUS_IS_OK(status)) {
2808 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2809 nt_errstr(status)));
2810 stream_terminate_connection(srv_conn, nt_errstr(status));
2816 * This fills in dcesrv_conn->endpoint with the endpoint
2817 * associated with the socket. From this point on we know
2818 * which (group of) services we are handling, but not the
2819 * specific interface.
2822 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2824 dcesrv_sock->endpoint,
2825 srv_conn->session_info,
2826 srv_conn->event.ctx,
2827 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2829 if (!NT_STATUS_IS_OK(status)) {
2830 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2831 nt_errstr(status)));
2832 stream_terminate_connection(srv_conn, nt_errstr(status));
2836 dcesrv_conn->transport.private_data = srv_conn;
2837 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2838 dcesrv_conn->transport.terminate_connection = dcesrv_transport_terminate_connection;
2840 TALLOC_FREE(srv_conn->event.fde);
2842 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2843 if (!dcesrv_conn->send_queue) {
2844 status = NT_STATUS_NO_MEMORY;
2845 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2846 nt_errstr(status)));
2847 stream_terminate_connection(srv_conn, nt_errstr(status));
2851 if (transport == NCACN_NP) {
2852 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2853 &srv_conn->tstream);
2855 ret = tstream_bsd_existing_socket(dcesrv_conn,
2856 socket_get_fd(srv_conn->socket),
2857 &dcesrv_conn->stream);
2859 status = map_nt_error_from_unix_common(errno);
2860 DEBUG(0, ("dcesrv_sock_accept: "
2861 "failed to setup tstream: %s\n",
2862 nt_errstr(status)));
2863 stream_terminate_connection(srv_conn, nt_errstr(status));
2866 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2869 dcesrv_conn->local_address = srv_conn->local_address;
2870 dcesrv_conn->remote_address = srv_conn->remote_address;
2872 if (transport == NCALRPC) {
2877 sock_fd = socket_get_fd(srv_conn->socket);
2878 if (sock_fd == -1) {
2879 stream_terminate_connection(
2880 srv_conn, "socket_get_fd failed\n");
2884 ret = getpeereid(sock_fd, &uid, &gid);
2886 status = map_nt_error_from_unix_common(errno);
2887 DEBUG(0, ("dcesrv_sock_accept: "
2888 "getpeereid() failed for NCALRPC: %s\n",
2889 nt_errstr(status)));
2890 stream_terminate_connection(srv_conn, nt_errstr(status));
2893 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2894 struct tsocket_address *r = NULL;
2896 ret = tsocket_address_unix_from_path(dcesrv_conn,
2897 AS_SYSTEM_MAGIC_PATH_TOKEN,
2900 status = map_nt_error_from_unix_common(errno);
2901 DEBUG(0, ("dcesrv_sock_accept: "
2902 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2903 nt_errstr(status)));
2904 stream_terminate_connection(srv_conn, nt_errstr(status));
2907 dcesrv_conn->remote_address = r;
2911 srv_conn->private_data = dcesrv_conn;
2913 status = dcesrv_connection_loop_start(dcesrv_conn);
2914 if (!NT_STATUS_IS_OK(status)) {
2915 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2916 nt_errstr(status)));
2917 stream_terminate_connection(srv_conn, nt_errstr(status));
2924 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2926 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2928 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2929 struct dcesrv_connection);
2930 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2931 struct ncacn_packet *pkt;
2935 if (dce_conn->terminate) {
2937 * if the current connection is broken
2938 * we need to clean it up before any other connection
2940 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2941 dcesrv_cleanup_broken_connections(dce_ctx);
2945 dcesrv_cleanup_broken_connections(dce_ctx);
2947 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2949 TALLOC_FREE(subreq);
2950 if (!NT_STATUS_IS_OK(status)) {
2951 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2955 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2956 if (!NT_STATUS_IS_OK(status)) {
2957 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2962 * This is used to block the connection during
2963 * pending authentication.
2965 if (dce_conn->wait_send != NULL) {
2966 subreq = dce_conn->wait_send(dce_conn,
2967 dce_conn->event_ctx,
2968 dce_conn->wait_private);
2970 status = NT_STATUS_NO_MEMORY;
2971 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2974 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2978 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2979 dce_conn->event_ctx,
2982 status = NT_STATUS_NO_MEMORY;
2983 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2986 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2989 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2991 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2992 struct dcesrv_connection);
2993 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2996 if (dce_conn->terminate) {
2998 * if the current connection is broken
2999 * we need to clean it up before any other connection
3001 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3002 dcesrv_cleanup_broken_connections(dce_ctx);
3006 dcesrv_cleanup_broken_connections(dce_ctx);
3008 status = dce_conn->wait_recv(subreq);
3009 dce_conn->wait_send = NULL;
3010 dce_conn->wait_recv = NULL;
3011 dce_conn->wait_private = NULL;
3012 TALLOC_FREE(subreq);
3013 if (!NT_STATUS_IS_OK(status)) {
3014 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3018 status = dcesrv_connection_loop_start(dce_conn);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3025 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
3027 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
3028 struct dcesrv_connection);
3029 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
3032 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
3034 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
3035 struct dcesrv_connection);
3036 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
3040 static const struct stream_server_ops dcesrv_stream_ops = {
3042 .accept_connection = dcesrv_sock_accept,
3043 .recv_handler = dcesrv_sock_recv,
3044 .send_handler = dcesrv_sock_send,
3047 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
3048 struct loadparm_context *lp_ctx,
3049 struct dcesrv_endpoint *e,
3050 struct tevent_context *event_ctx,
3051 const struct model_ops *model_ops,
3052 void *process_context)
3054 struct dcesrv_socket_context *dcesrv_sock;
3057 const char *endpoint;
3059 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3060 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3062 /* remember the endpoint of this socket */
3063 dcesrv_sock->endpoint = e;
3064 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3066 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3068 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3069 model_ops, &dcesrv_stream_ops,
3070 "unix", endpoint, &port,
3071 lpcfg_socket_options(lp_ctx),
3072 dcesrv_sock, process_context);
3073 if (!NT_STATUS_IS_OK(status)) {
3074 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
3075 endpoint, nt_errstr(status)));
3081 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
3082 struct loadparm_context *lp_ctx,
3083 struct dcesrv_endpoint *e,
3084 struct tevent_context *event_ctx,
3085 const struct model_ops *model_ops,
3086 void *process_context)
3088 struct dcesrv_socket_context *dcesrv_sock;
3092 const char *endpoint;
3094 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3096 if (endpoint == NULL) {
3098 * No identifier specified: use DEFAULT.
3100 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
3101 * no endpoint and let the epmapper worry about it.
3103 endpoint = "DEFAULT";
3104 status = dcerpc_binding_set_string_option(e->ep_description,
3107 if (!NT_STATUS_IS_OK(status)) {
3108 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
3109 nt_errstr(status)));
3114 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
3117 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3118 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3120 /* remember the endpoint of this socket */
3121 dcesrv_sock->endpoint = e;
3122 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3124 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3125 model_ops, &dcesrv_stream_ops,
3126 "unix", full_path, &port,
3127 lpcfg_socket_options(lp_ctx),
3128 dcesrv_sock, process_context);
3129 if (!NT_STATUS_IS_OK(status)) {
3130 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3131 endpoint, full_path, nt_errstr(status)));
3136 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3137 struct loadparm_context *lp_ctx,
3138 struct dcesrv_endpoint *e,
3139 struct tevent_context *event_ctx,
3140 const struct model_ops *model_ops,
3141 void *process_context)
3143 struct dcesrv_socket_context *dcesrv_sock;
3145 const char *endpoint;
3147 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3148 if (endpoint == NULL) {
3149 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3150 return NT_STATUS_INVALID_PARAMETER;
3153 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3154 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3156 /* remember the endpoint of this socket */
3157 dcesrv_sock->endpoint = e;
3158 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3160 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3161 model_ops, &dcesrv_stream_ops,
3163 dcesrv_sock, process_context);
3164 if (!NT_STATUS_IS_OK(status)) {
3165 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3166 endpoint, nt_errstr(status)));
3170 return NT_STATUS_OK;
3174 add a socket address to the list of events, one event per dcerpc endpoint
3176 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3177 struct dcesrv_endpoint *e,
3178 struct tevent_context *event_ctx,
3179 const struct model_ops *model_ops,
3180 const char *address,
3181 void *process_context)
3183 struct dcesrv_socket_context *dcesrv_sock;
3186 const char *endpoint;
3189 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3190 if (endpoint != NULL) {
3191 port = atoi(endpoint);
3194 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3195 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3197 /* remember the endpoint of this socket */
3198 dcesrv_sock->endpoint = e;
3199 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3201 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3202 model_ops, &dcesrv_stream_ops,
3203 "ip", address, &port,
3204 lpcfg_socket_options(dce_ctx->lp_ctx),
3205 dcesrv_sock, process_context);
3206 if (!NT_STATUS_IS_OK(status)) {
3207 struct dcesrv_if_list *iface;
3208 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3210 for (iface = e->interface_list; iface; iface = iface->next) {
3211 DEBUGADD(0, ("%s ", iface->iface.name));
3213 DEBUGADD(0, ("failed - %s\n",
3214 nt_errstr(status)));
3218 snprintf(port_str, sizeof(port_str), "%u", port);
3220 status = dcerpc_binding_set_string_option(e->ep_description,
3221 "endpoint", port_str);
3222 if (!NT_STATUS_IS_OK(status)) {
3223 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3224 port_str, nt_errstr(status)));
3227 struct dcesrv_if_list *iface;
3228 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3229 address, port_str));
3230 for (iface = e->interface_list; iface; iface = iface->next) {
3231 DEBUGADD(4, ("%s ", iface->iface.name));
3233 DEBUGADD(4, ("\n"));
3236 return NT_STATUS_OK;
3239 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3241 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3242 struct loadparm_context *lp_ctx,
3243 struct dcesrv_endpoint *e,
3244 struct tevent_context *event_ctx,
3245 const struct model_ops *model_ops,
3246 void *process_context)
3250 /* Add TCP/IP sockets */
3251 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3254 struct interface *ifaces;
3256 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3258 num_interfaces = iface_list_count(ifaces);
3259 for(i = 0; i < num_interfaces; i++) {
3260 const char *address = iface_list_n_ip(ifaces, i);
3261 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3264 NT_STATUS_NOT_OK_RETURN(status);
3269 size_t num_binds = 0;
3270 wcard = iface_list_wildcard(dce_ctx);
3271 NT_STATUS_HAVE_NO_MEMORY(wcard);
3272 for (i=0; wcard[i]; i++) {
3273 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3274 model_ops, wcard[i],
3276 if (NT_STATUS_IS_OK(status)) {
3281 if (num_binds == 0) {
3282 return NT_STATUS_INVALID_PARAMETER_MIX;
3286 return NT_STATUS_OK;
3289 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3290 struct loadparm_context *lp_ctx,
3291 struct dcesrv_endpoint *e,
3292 struct tevent_context *event_ctx,
3293 const struct model_ops *model_ops,
3294 void *process_context)
3296 enum dcerpc_transport_t transport =
3297 dcerpc_binding_get_transport(e->ep_description);
3299 switch (transport) {
3300 case NCACN_UNIX_STREAM:
3301 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3302 model_ops, process_context);
3305 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3306 model_ops, process_context);
3309 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3310 model_ops, process_context);
3313 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3314 model_ops, process_context);
3317 return NT_STATUS_NOT_SUPPORTED;
3323 * retrieve credentials from a dce_call
3325 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3327 struct dcesrv_auth *auth = dce_call->auth_state;
3328 SMB_ASSERT(auth->auth_finished);
3329 return auth->session_info->credentials;
3333 * returns true if this is an authenticated call
3335 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3337 struct dcesrv_auth *auth = dce_call->auth_state;
3338 enum security_user_level level;
3339 SMB_ASSERT(auth->auth_finished);
3340 level = security_session_user_level(auth->session_info, NULL);
3341 return level >= SECURITY_USER;
3345 * retrieve account_name for a dce_call
3347 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3349 struct dcesrv_auth *auth = dce_call->auth_state;
3350 SMB_ASSERT(auth->auth_finished);
3351 return auth->session_info->info->account_name;
3355 * retrieve session_info from a dce_call
3357 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3359 struct dcesrv_auth *auth = dce_call->auth_state;
3360 SMB_ASSERT(auth->auth_finished);
3361 return auth->session_info;
3365 * retrieve auth type/level from a dce_call
3367 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3368 enum dcerpc_AuthType *auth_type,
3369 enum dcerpc_AuthLevel *auth_level)
3371 struct dcesrv_auth *auth = dce_call->auth_state;
3373 SMB_ASSERT(auth->auth_finished);
3375 if (auth_type != NULL) {
3376 *auth_type = auth->auth_type;
3378 if (auth_level != NULL) {
3379 *auth_level = auth->auth_level;
3383 _PUBLIC_ struct imessaging_context *dcesrv_imessaging_context(
3384 struct dcesrv_connection *conn)
3386 struct stream_connection *srv_conn =
3387 talloc_get_type_abort(conn->transport.private_data,
3388 struct stream_connection);
3389 return srv_conn->msg_ctx;
3392 _PUBLIC_ struct server_id dcesrv_server_id(struct dcesrv_connection *conn)
3394 struct stream_connection *srv_conn =
3395 talloc_get_type_abort(conn->transport.private_data,
3396 struct stream_connection);
3397 return srv_conn->server_id;
3400 void log_successful_dcesrv_authz_event(struct dcesrv_call_state *call)
3402 struct dcesrv_auth *auth = call->auth_state;
3403 enum dcerpc_transport_t transport =
3404 dcerpc_binding_get_transport(call->conn->endpoint->ep_description);
3405 struct imessaging_context *imsg_ctx =
3406 dcesrv_imessaging_context(call->conn);
3407 const char *auth_type = derpc_transport_string_by_transport(transport);
3408 const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
3410 if (transport == NCACN_NP) {
3411 transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
3415 * Log the authorization to this RPC interface. This
3416 * covered ncacn_np pass-through auth, and anonymous
3417 * DCE/RPC (eg epmapper, netlogon etc)
3419 log_successful_authz_event(imsg_ctx,
3420 call->conn->dce_ctx->lp_ctx,
3421 call->conn->remote_address,
3422 call->conn->local_address,
3425 transport_protection,
3426 auth->session_info);
3428 auth->auth_audited = true;
3431 NTSTATUS dcesrv_gensec_prepare(TALLOC_CTX *mem_ctx,
3432 struct dcesrv_call_state *call,
3433 struct gensec_security **out)
3435 struct cli_credentials *server_creds = NULL;
3436 struct imessaging_context *imsg_ctx =
3437 dcesrv_imessaging_context(call->conn);
3440 server_creds = cli_credentials_init(call->auth_state);
3441 if (!server_creds) {
3442 DEBUG(1, ("Failed to init server credentials\n"));
3443 return NT_STATUS_NO_MEMORY;
3446 cli_credentials_set_conf(server_creds, call->conn->dce_ctx->lp_ctx);
3448 status = cli_credentials_set_machine_account(server_creds,
3449 call->conn->dce_ctx->lp_ctx);
3450 if (!NT_STATUS_IS_OK(status)) {
3451 DEBUG(1, ("Failed to obtain server credentials: %s\n",
3452 nt_errstr(status)));
3453 talloc_free(server_creds);
3457 return samba_server_gensec_start(mem_ctx,
3460 call->conn->dce_ctx->lp_ctx,
3466 void dcesrv_transport_terminate_connection(struct dcesrv_connection *dce_conn,
3469 struct stream_connection *srv_conn =
3470 talloc_get_type_abort(dce_conn->transport.private_data,
3471 struct stream_connection);
3472 stream_terminate_connection(srv_conn, reason);
3475 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
3477 struct tevent_req *subreq;
3479 subreq = dcerpc_read_ncacn_packet_send(conn,
3482 if (subreq == NULL) {
3483 return NT_STATUS_NO_MEMORY;
3485 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
3487 return NT_STATUS_OK;