2 Unix SMB/CIFS implementation.
4 server side dcerpc core code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44 #include "../lib/util/tevent_ntstatus.h"
46 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
47 const struct dcerpc_bind *b,
48 struct dcerpc_ack_ctx *ack_ctx_list);
51 find an association group given a assoc_group_id
53 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
58 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
62 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
66 take a reference to an existing association group
68 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
69 struct dcesrv_context *dce_ctx,
72 struct dcesrv_assoc_group *assoc_group;
74 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
75 if (assoc_group == NULL) {
76 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
79 return talloc_reference(mem_ctx, assoc_group);
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
85 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
87 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
94 allocate a new association group
96 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
97 struct dcesrv_context *dce_ctx)
99 struct dcesrv_assoc_group *assoc_group;
102 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103 if (assoc_group == NULL) {
107 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
109 talloc_free(assoc_group);
110 DEBUG(0,(__location__ ": Out of association groups!\n"));
114 assoc_group->id = id;
115 assoc_group->dce_ctx = dce_ctx;
117 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
124 see if two endpoints match
126 static bool endpoints_match(const struct dcerpc_binding *ep1,
127 const struct dcerpc_binding *ep2)
129 enum dcerpc_transport_t t1;
130 enum dcerpc_transport_t t2;
134 t1 = dcerpc_binding_get_transport(ep1);
135 t2 = dcerpc_binding_get_transport(ep2);
137 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
138 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
148 if (strcasecmp(e1, e2) != 0) {
156 find an endpoint in the dcesrv_context
158 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
159 const struct dcerpc_binding *ep_description)
161 struct dcesrv_endpoint *ep;
162 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
163 if (endpoints_match(ep->ep_description, ep_description)) {
171 find a registered context_id from a bind or alter_context
173 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
176 struct dcesrv_connection_context *c;
177 for (c=conn->contexts;c;c=c->next) {
178 if (c->context_id == context_id) return c;
184 see if a uuid and if_version match to an interface
186 static bool interface_match(const struct dcesrv_interface *if1,
187 const struct dcesrv_interface *if2)
189 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
190 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
194 find the interface operations on any endpoint with this binding
196 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
197 struct dcerpc_binding *binding,
198 const struct dcesrv_interface *iface)
200 struct dcesrv_endpoint *ep;
201 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
202 if (endpoints_match(ep->ep_description, binding)) {
203 struct dcesrv_if_list *ifl;
204 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
205 if (interface_match(&(ifl->iface), iface)) {
206 return &(ifl->iface);
215 see if a uuid and if_version match to an interface
217 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
218 const struct GUID *uuid, uint32_t if_version)
220 return (iface->syntax_id.if_version == if_version &&
221 GUID_equal(&iface->syntax_id.uuid, uuid));
225 find the interface operations on an endpoint by uuid
227 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
228 const struct GUID *uuid, uint32_t if_version)
230 struct dcesrv_if_list *ifl;
231 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
232 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
233 return &(ifl->iface);
240 find the earlier parts of a fragmented call awaiting reassembily
242 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
244 struct dcesrv_call_state *c;
245 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
246 if (c->pkt.call_id == call_id) {
254 register an interface on an endpoint
256 An endpoint is one unix domain socket (for ncalrpc), one TCP port
257 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
259 Each endpoint can have many interfaces such as netlogon, lsa or
260 samr. Some have essentially the full set.
262 This is driven from the set of interfaces listed in each IDL file
263 via the PIDL generated *__op_init_server() functions.
265 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
267 const struct dcesrv_interface *iface,
268 const struct security_descriptor *sd)
270 struct dcesrv_endpoint *ep;
271 struct dcesrv_if_list *ifl;
272 struct dcerpc_binding *binding;
275 enum dcerpc_transport_t transport;
276 char *ep_string = NULL;
277 bool use_single_process = true;
278 const char *ep_process_string;
281 * If we are not using handles, there is no need for force
282 * this service into using a single process.
284 * However, due to the way we listen for RPC packets, we can
285 * only do this if we have a single service per pipe or TCP
286 * port, so we still force a single combined process for
289 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
290 use_single_process = false;
293 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
295 if (NT_STATUS_IS_ERR(status)) {
296 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
300 transport = dcerpc_binding_get_transport(binding);
301 if (transport == NCACN_IP_TCP) {
306 * First check if there is already a port specified, eg
307 * for epmapper on ncacn_ip_tcp:[135]
310 = dcerpc_binding_get_string_option(binding,
312 if (endpoint == NULL) {
313 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
314 "rpc server port", iface->name, 0);
317 * For RPC services that are not set to use a single
318 * process, we do not default to using the 'rpc server
319 * port' because that would cause a double-bind on
322 if (port == 0 && !use_single_process) {
323 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
326 snprintf(port_str, sizeof(port_str), "%u", port);
327 status = dcerpc_binding_set_string_option(binding,
330 if (!NT_STATUS_IS_OK(status)) {
337 /* see if the interface is already registered on the endpoint */
338 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
339 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
340 iface->name, ep_name));
341 return NT_STATUS_OBJECT_NAME_COLLISION;
344 /* check if this endpoint exists
346 ep = find_endpoint(dce_ctx, binding);
350 * We want a new port on ncacn_ip_tcp for NETLOGON, so
351 * it can be multi-process. Other processes can also
352 * listen on distinct ports, if they have one forced
353 * in the code above with eg 'rpc server port:drsuapi = 1027'
355 * If we have mulitiple endpoints on port 0, they each
356 * get an epemeral port (currently by walking up from
359 * Because one endpoint can only have one process
360 * model, we add a new IP_TCP endpoint for each model.
362 * This works in conjunction with the forced overwrite
363 * of ep->use_single_process below.
365 if (ep->use_single_process != use_single_process
366 && transport == NCACN_IP_TCP) {
371 if (ep == NULL || add_ep) {
372 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
374 return NT_STATUS_NO_MEMORY;
377 ep->ep_description = talloc_move(ep, &binding);
380 /* add mgmt interface */
381 ifl = talloc_zero(ep, struct dcesrv_if_list);
383 return NT_STATUS_NO_MEMORY;
386 ifl->iface = dcesrv_get_mgmt_interface();
388 DLIST_ADD(ep->interface_list, ifl);
392 * By default don't force into a single process, but if any
393 * interface on this endpoint on this service uses handles
394 * (most do), then we must force into single process mode
396 * By overwriting this each time a new interface is added to
397 * this endpoint, we end up with the most restrictive setting.
399 if (use_single_process) {
400 ep->use_single_process = true;
403 /* talloc a new interface list element */
404 ifl = talloc_zero(ep, struct dcesrv_if_list);
406 return NT_STATUS_NO_MEMORY;
409 /* copy the given interface struct to the one on the endpoints interface list */
410 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
412 /* if we have a security descriptor given,
413 * we should see if we can set it up on the endpoint
416 /* if there's currently no security descriptor given on the endpoint
419 if (ep->sd == NULL) {
420 ep->sd = security_descriptor_copy(ep, sd);
423 /* if now there's no security descriptor given on the endpoint
424 * something goes wrong, either we failed to copy the security descriptor
425 * or there was already one on the endpoint
427 if (ep->sd != NULL) {
428 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
429 " on endpoint '%s'\n",
430 iface->name, ep_name));
431 if (add_ep) free(ep);
433 return NT_STATUS_OBJECT_NAME_COLLISION;
437 /* finally add the interface on the endpoint */
438 DLIST_ADD(ep->interface_list, ifl);
440 /* if it's a new endpoint add it to the dcesrv_context */
442 DLIST_ADD(dce_ctx->endpoint_list, ep);
445 /* Re-get the string as we may have set a port */
446 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
448 if (use_single_process) {
449 ep_process_string = "single process required";
451 ep_process_string = "multi process compatible";
454 DBG_INFO("dcesrv_interface_register: interface '%s' "
455 "registered on endpoint '%s' (%s)\n",
456 iface->name, ep_string, ep_process_string);
457 TALLOC_FREE(ep_string);
462 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
463 DATA_BLOB *session_key)
465 if (auth->session_info == NULL) {
466 return NT_STATUS_NO_USER_SESSION_KEY;
469 if (auth->session_info->session_key.length == 0) {
470 return NT_STATUS_NO_USER_SESSION_KEY;
473 *session_key = auth->session_info->session_key;
477 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
478 DATA_BLOB *session_key)
480 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
481 return NT_STATUS_NO_USER_SESSION_KEY;
484 return dcesrv_session_info_session_key(auth, session_key);
487 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
488 DATA_BLOB *session_key)
490 return dcerpc_generic_session_key(NULL, session_key);
494 * Fetch the authentication session key if available.
496 * This is the key generated by a gensec authentication.
499 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
500 DATA_BLOB *session_key)
502 struct dcesrv_auth *auth = call->auth_state;
504 return dcesrv_session_info_session_key(auth, session_key);
508 * Fetch the transport session key if available.
509 * Typically this is the SMB session key
510 * or a fixed key for local transports.
512 * The key is always truncated to 16 bytes.
514 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
515 DATA_BLOB *session_key)
517 struct dcesrv_auth *auth = call->auth_state;
520 if (auth->session_key_fn == NULL) {
521 return NT_STATUS_NO_USER_SESSION_KEY;
524 status = auth->session_key_fn(auth, session_key);
525 if (!NT_STATUS_IS_OK(status)) {
529 session_key->length = MIN(session_key->length, 16);
534 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
536 const struct dcesrv_endpoint *ep = conn->endpoint;
537 enum dcerpc_transport_t transport =
538 dcerpc_binding_get_transport(ep->ep_description);
539 struct dcesrv_auth *auth = NULL;
541 auth = talloc_zero(conn, struct dcesrv_auth);
548 auth->session_key_fn = dcesrv_remote_session_key;
551 case NCACN_UNIX_STREAM:
552 auth->session_key_fn = dcesrv_local_fixed_session_key;
556 * All other's get a NULL pointer, which
557 * results in NT_STATUS_NO_USER_SESSION_KEY
566 connect to a dcerpc endpoint
568 static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
570 const struct dcesrv_endpoint *ep,
571 struct auth_session_info *session_info,
572 struct tevent_context *event_ctx,
573 struct imessaging_context *msg_ctx,
574 struct server_id server_id,
575 uint32_t state_flags,
576 struct dcesrv_connection **_p)
578 struct dcesrv_auth *auth = NULL;
579 struct dcesrv_connection *p;
582 return NT_STATUS_ACCESS_DENIED;
585 p = talloc_zero(mem_ctx, struct dcesrv_connection);
586 NT_STATUS_HAVE_NO_MEMORY(p);
588 p->dce_ctx = dce_ctx;
590 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
591 p->event_ctx = event_ctx;
592 p->msg_ctx = msg_ctx;
593 p->server_id = server_id;
594 p->state_flags = state_flags;
595 p->allow_bind = true;
596 p->max_recv_frag = 5840;
597 p->max_xmit_frag = 5840;
598 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
600 auth = dcesrv_auth_create(p);
603 return NT_STATUS_NO_MEMORY;
606 auth->session_info = talloc_reference(auth, session_info);
607 if (auth->session_info == NULL) {
609 return NT_STATUS_NO_MEMORY;
612 p->default_auth_state = auth;
615 * For now we only support NDR32.
617 p->preferred_transfer = &ndr_transfer_syntax_ndr;
624 move a call from an existing linked list to the specified list. This
625 prevents bugs where we forget to remove the call from a previous
628 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
629 enum dcesrv_call_list list)
631 switch (call->list) {
632 case DCESRV_LIST_NONE:
634 case DCESRV_LIST_CALL_LIST:
635 DLIST_REMOVE(call->conn->call_list, call);
637 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
638 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
640 case DCESRV_LIST_PENDING_CALL_LIST:
641 DLIST_REMOVE(call->conn->pending_call_list, call);
646 case DCESRV_LIST_NONE:
648 case DCESRV_LIST_CALL_LIST:
649 DLIST_ADD_END(call->conn->call_list, call);
651 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
652 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
654 case DCESRV_LIST_PENDING_CALL_LIST:
655 DLIST_ADD_END(call->conn->pending_call_list, call);
660 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
663 if (call->conn->terminate != NULL) {
667 call->conn->allow_bind = false;
668 call->conn->allow_alter = false;
669 call->conn->allow_auth3 = false;
670 call->conn->allow_request = false;
672 call->conn->default_auth_state->auth_invalid = true;
674 call->terminate_reason = talloc_strdup(call, reason);
675 if (call->terminate_reason == NULL) {
676 call->terminate_reason = __location__;
681 return a dcerpc bind_nak
683 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
685 struct ncacn_packet pkt;
686 struct dcerpc_bind_nak_version version;
687 struct data_blob_list_item *rep;
689 static const uint8_t _pad[3] = { 0, };
692 * We add the call to the pending_call_list
693 * in order to defer the termination.
695 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
697 /* setup a bind_nak */
698 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
700 pkt.call_id = call->pkt.call_id;
701 pkt.ptype = DCERPC_PKT_BIND_NAK;
702 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
703 pkt.u.bind_nak.reject_reason = reason;
704 version.rpc_vers = 5;
705 version.rpc_vers_minor = 0;
706 pkt.u.bind_nak.num_versions = 1;
707 pkt.u.bind_nak.versions = &version;
708 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
710 rep = talloc_zero(call, struct data_blob_list_item);
712 return NT_STATUS_NO_MEMORY;
715 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
716 if (!NT_STATUS_IS_OK(status)) {
720 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
722 DLIST_ADD_END(call->replies, rep);
723 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
725 if (call->conn->call_list && call->conn->call_list->replies) {
726 if (call->conn->transport.report_output_data) {
727 call->conn->transport.report_output_data(call->conn);
734 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
738 * We add the call to the pending_call_list
739 * in order to defer the termination.
741 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
743 return dcesrv_fault_with_flags(call, fault_code,
744 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
747 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
749 DLIST_REMOVE(c->conn->contexts, c);
751 if (c->iface && c->iface->unbind) {
752 c->iface->unbind(c, c->iface);
759 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
761 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
762 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
763 enum dcerpc_transport_t transport =
764 dcerpc_binding_get_transport(endpoint->ep_description);
765 struct dcesrv_connection_context *context = dce_call->context;
766 const struct dcesrv_interface *iface = context->iface;
768 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
770 if (transport == NCALRPC) {
771 context->allow_connect = true;
776 * allow overwrite per interface
777 * allow dcerpc auth level connect:<interface>
779 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
780 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
781 "allow dcerpc auth level connect",
783 context->allow_connect);
786 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
787 const struct dcesrv_interface *iface)
789 if (dce_call->context == NULL) {
790 return NT_STATUS_INTERNAL_ERROR;
794 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
795 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
797 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
801 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
802 const struct dcesrv_interface *iface)
804 if (dce_call->context == NULL) {
805 return NT_STATUS_INTERNAL_ERROR;
808 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
812 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
813 const struct dcesrv_interface *iface)
815 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
816 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
817 enum dcerpc_transport_t transport =
818 dcerpc_binding_get_transport(endpoint->ep_description);
819 struct dcesrv_connection_context *context = dce_call->context;
821 if (context == NULL) {
822 return NT_STATUS_INTERNAL_ERROR;
825 if (transport == NCALRPC) {
826 context->allow_connect = true;
831 * allow overwrite per interface
832 * allow dcerpc auth level connect:<interface>
834 context->allow_connect = false;
835 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
836 "allow dcerpc auth level connect",
838 context->allow_connect);
842 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
843 const struct dcesrv_interface *iface)
845 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
846 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
847 enum dcerpc_transport_t transport =
848 dcerpc_binding_get_transport(endpoint->ep_description);
849 struct dcesrv_connection_context *context = dce_call->context;
851 if (context == NULL) {
852 return NT_STATUS_INTERNAL_ERROR;
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 = true;
865 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
866 "allow dcerpc auth level connect",
868 context->allow_connect);
872 struct dcesrv_conn_auth_wait_context {
873 struct tevent_req *req;
878 struct dcesrv_conn_auth_wait_state {
882 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
883 struct tevent_context *ev,
886 struct dcesrv_conn_auth_wait_context *auth_wait =
887 talloc_get_type_abort(private_data,
888 struct dcesrv_conn_auth_wait_context);
889 struct tevent_req *req = NULL;
890 struct dcesrv_conn_auth_wait_state *state = NULL;
892 req = tevent_req_create(mem_ctx, &state,
893 struct dcesrv_conn_auth_wait_state);
897 auth_wait->req = req;
899 tevent_req_defer_callback(req, ev);
901 if (!auth_wait->done) {
905 if (tevent_req_nterror(req, auth_wait->status)) {
906 return tevent_req_post(req, ev);
909 tevent_req_done(req);
910 return tevent_req_post(req, ev);
913 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
915 return tevent_req_simple_recv_ntstatus(req);
918 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
920 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
922 if (conn->wait_send != NULL) {
923 return NT_STATUS_INTERNAL_ERROR;
926 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
927 if (auth_wait == NULL) {
928 return NT_STATUS_NO_MEMORY;
931 conn->wait_private = auth_wait;
932 conn->wait_send = dcesrv_conn_auth_wait_send;
933 conn->wait_recv = dcesrv_conn_auth_wait_recv;
937 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
940 struct dcesrv_conn_auth_wait_context *auth_wait =
941 talloc_get_type_abort(conn->wait_private,
942 struct dcesrv_conn_auth_wait_context);
944 auth_wait->done = true;
945 auth_wait->status = status;
947 if (auth_wait->req == NULL) {
951 if (tevent_req_nterror(auth_wait->req, status)) {
955 tevent_req_done(auth_wait->req);
958 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
960 static void dcesrv_bind_done(struct tevent_req *subreq);
963 handle a bind request
965 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
967 struct dcesrv_connection *conn = call->conn;
968 struct ncacn_packet *pkt = &call->ack_pkt;
970 uint32_t extra_flags = 0;
971 uint16_t max_req = 0;
972 uint16_t max_rep = 0;
973 const char *ep_prefix = "";
974 const char *endpoint = NULL;
975 struct dcesrv_auth *auth = call->auth_state;
976 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
977 struct dcerpc_ack_ctx *ack_features = NULL;
978 struct tevent_req *subreq = NULL;
981 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
983 call->pkt.u.bind.auth_info.length,
984 0, /* required flags */
985 DCERPC_PFC_FLAG_FIRST |
986 DCERPC_PFC_FLAG_LAST |
987 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
988 0x08 | /* this is not defined, but should be ignored */
989 DCERPC_PFC_FLAG_CONC_MPX |
990 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
991 DCERPC_PFC_FLAG_MAYBE |
992 DCERPC_PFC_FLAG_OBJECT_UUID);
993 if (!NT_STATUS_IS_OK(status)) {
994 return dcesrv_bind_nak(call,
995 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
998 /* max_recv_frag and max_xmit_frag result always in the same value! */
999 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
1000 call->pkt.u.bind.max_recv_frag);
1002 * The values are between 2048 and 5840 tested against Windows 2012R2
1003 * via ncacn_ip_tcp on port 135.
1005 max_req = MAX(2048, max_req);
1006 max_rep = MIN(max_req, call->conn->max_recv_frag);
1007 /* They are truncated to an 8 byte boundary. */
1010 /* max_recv_frag and max_xmit_frag result always in the same value! */
1011 call->conn->max_recv_frag = max_rep;
1012 call->conn->max_xmit_frag = max_rep;
1015 if provided, check the assoc_group is valid
1017 if (call->pkt.u.bind.assoc_group_id != 0) {
1018 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
1019 call->conn->dce_ctx,
1020 call->pkt.u.bind.assoc_group_id);
1022 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
1023 call->conn->dce_ctx);
1027 * The NETLOGON server does not use handles and so
1028 * there is no need to support association groups, but
1029 * we need to give back a number regardless.
1031 * We have to do this when it is not run as a single process,
1032 * because then it can't see the other valid association
1033 * groups. We handle this genericly for all endpoints not
1034 * running in single process mode.
1036 * We know which endpoint we are on even before checking the
1037 * iface UUID, so for simplicity we enforce the same policy
1038 * for all interfaces on the endpoint.
1040 * This means that where NETLOGON
1041 * shares an endpoint (such as ncalrpc or of 'lsa over
1042 * netlogon' is set) we will still check association groups.
1046 if (call->conn->assoc_group == NULL &&
1047 !call->conn->endpoint->use_single_process) {
1048 call->conn->assoc_group
1049 = dcesrv_assoc_group_new(call->conn,
1050 call->conn->dce_ctx);
1052 if (call->conn->assoc_group == NULL) {
1053 return dcesrv_bind_nak(call, 0);
1056 if (call->pkt.u.bind.num_contexts < 1) {
1057 return dcesrv_bind_nak(call, 0);
1060 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1061 call->pkt.u.bind.num_contexts);
1062 if (ack_ctx_list == NULL) {
1063 return dcesrv_bind_nak(call, 0);
1067 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1068 * dcesrv_check_or_create_context()) and do some protocol validation
1069 * and set sane defaults.
1071 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1072 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1073 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1074 bool is_feature = false;
1075 uint64_t features = 0;
1077 if (c->num_transfer_syntaxes == 0) {
1078 return dcesrv_bind_nak(call, 0);
1081 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1082 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1085 * It's only treated as bind time feature request, if the first
1086 * transfer_syntax matches, all others are ignored.
1088 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1094 if (ack_features != NULL) {
1096 * Only one bind time feature context is allowed.
1098 return dcesrv_bind_nak(call, 0);
1102 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1103 a->reason.negotiate = 0;
1104 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1105 /* not supported yet */
1107 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1108 a->reason.negotiate |=
1109 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1112 call->conn->bind_time_features = a->reason.negotiate;
1116 * Try to negotiate one new presentation context.
1118 * Deep in here we locate the iface (by uuid) that the client
1119 * requested, from the list of interfaces on the
1120 * call->conn->endpoint, and call iface->bind() on that iface.
1122 * call->conn was set up at the accept() of the socket, and
1123 * call->conn->endpoint has a list of interfaces restricted to
1124 * this port or pipe.
1126 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1127 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1128 return dcesrv_bind_nak(call, 0);
1130 if (!NT_STATUS_IS_OK(status)) {
1135 * At this point we still don't know which interface (eg
1136 * netlogon, lsa, drsuapi) the caller requested in this bind!
1137 * The most recently added context is available as the first
1138 * element in the linked list at call->conn->contexts, that is
1139 * call->conn->contexts->iface, but they may not have
1140 * requested one at all!
1143 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1144 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1145 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1146 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1149 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1150 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1154 * After finding the interface and setting up the NDR
1155 * transport negotiation etc, handle any authentication that
1156 * is being requested.
1158 if (!dcesrv_auth_bind(call)) {
1160 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1162 * With DCERPC_AUTH_LEVEL_NONE, we get the
1163 * reject_reason in auth->auth_context_id.
1165 return dcesrv_bind_nak(call, auth->auth_context_id);
1169 * This must a be a temporary failure e.g. talloc or invalid
1170 * configuration, e.g. no machine account.
1172 return dcesrv_bind_nak(call,
1173 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1176 /* setup a bind_ack */
1177 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1178 pkt->auth_length = 0;
1179 pkt->call_id = call->pkt.call_id;
1180 pkt->ptype = DCERPC_PKT_BIND_ACK;
1181 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1182 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1183 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1184 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1186 endpoint = dcerpc_binding_get_string_option(
1187 call->conn->endpoint->ep_description,
1189 if (endpoint == NULL) {
1193 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1195 * TODO: check if this is really needed
1197 * Or if we should fix this in our idl files.
1199 ep_prefix = "\\PIPE\\";
1203 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1206 if (pkt->u.bind_ack.secondary_address == NULL) {
1207 return NT_STATUS_NO_MEMORY;
1209 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1210 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1211 pkt->u.bind_ack.auth_info = data_blob_null;
1213 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 return dcesrv_bind_nak(call, 0);
1218 if (auth->auth_finished) {
1219 return dcesrv_auth_reply(call);
1222 subreq = gensec_update_send(call, call->event_ctx,
1223 auth->gensec_security,
1224 call->in_auth_info.credentials);
1225 if (subreq == NULL) {
1226 return NT_STATUS_NO_MEMORY;
1228 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1230 return dcesrv_conn_auth_wait_setup(conn);
1233 static void dcesrv_bind_done(struct tevent_req *subreq)
1235 struct dcesrv_call_state *call =
1236 tevent_req_callback_data(subreq,
1237 struct dcesrv_call_state);
1238 struct dcesrv_connection *conn = call->conn;
1241 status = gensec_update_recv(subreq, call,
1242 &call->out_auth_info->credentials);
1243 TALLOC_FREE(subreq);
1245 status = dcesrv_auth_complete(call, status);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 status = dcesrv_bind_nak(call, 0);
1248 dcesrv_conn_auth_wait_finished(conn, status);
1252 status = dcesrv_auth_reply(call);
1253 dcesrv_conn_auth_wait_finished(conn, status);
1257 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1259 struct ncacn_packet *pkt = &call->ack_pkt;
1260 struct data_blob_list_item *rep = NULL;
1263 rep = talloc_zero(call, struct data_blob_list_item);
1265 return NT_STATUS_NO_MEMORY;
1268 status = ncacn_push_auth(&rep->blob, call, pkt,
1269 call->out_auth_info);
1270 if (!NT_STATUS_IS_OK(status)) {
1274 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1276 DLIST_ADD_END(call->replies, rep);
1277 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1279 if (call->conn->call_list && call->conn->call_list->replies) {
1280 if (call->conn->transport.report_output_data) {
1281 call->conn->transport.report_output_data(call->conn);
1285 return NT_STATUS_OK;
1289 static void dcesrv_auth3_done(struct tevent_req *subreq);
1292 handle a auth3 request
1294 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1296 struct dcesrv_connection *conn = call->conn;
1297 struct dcesrv_auth *auth = call->auth_state;
1298 struct tevent_req *subreq = NULL;
1301 if (!call->conn->allow_auth3) {
1302 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1305 if (auth->auth_finished) {
1306 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1309 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1311 call->pkt.u.auth3.auth_info.length,
1312 0, /* required flags */
1313 DCERPC_PFC_FLAG_FIRST |
1314 DCERPC_PFC_FLAG_LAST |
1315 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1316 0x08 | /* this is not defined, but should be ignored */
1317 DCERPC_PFC_FLAG_CONC_MPX |
1318 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1319 DCERPC_PFC_FLAG_MAYBE |
1320 DCERPC_PFC_FLAG_OBJECT_UUID);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1325 /* handle the auth3 in the auth code */
1326 if (!dcesrv_auth_prepare_auth3(call)) {
1328 * we don't send a reply to a auth3 request,
1329 * except by a fault.
1331 * In anycase we mark the connection as
1334 auth->auth_invalid = true;
1335 if (call->fault_code != 0) {
1336 return dcesrv_fault_disconnect(call, call->fault_code);
1339 return NT_STATUS_OK;
1342 subreq = gensec_update_send(call, call->event_ctx,
1343 auth->gensec_security,
1344 call->in_auth_info.credentials);
1345 if (subreq == NULL) {
1346 return NT_STATUS_NO_MEMORY;
1348 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1350 return dcesrv_conn_auth_wait_setup(conn);
1353 static void dcesrv_auth3_done(struct tevent_req *subreq)
1355 struct dcesrv_call_state *call =
1356 tevent_req_callback_data(subreq,
1357 struct dcesrv_call_state);
1358 struct dcesrv_connection *conn = call->conn;
1359 struct dcesrv_auth *auth = call->auth_state;
1362 status = gensec_update_recv(subreq, call,
1363 &call->out_auth_info->credentials);
1364 TALLOC_FREE(subreq);
1366 status = dcesrv_auth_complete(call, status);
1367 if (!NT_STATUS_IS_OK(status)) {
1369 * we don't send a reply to a auth3 request,
1370 * except by a fault.
1372 * In anycase we mark the connection as
1375 auth->auth_invalid = true;
1376 if (call->fault_code != 0) {
1377 status = dcesrv_fault_disconnect(call, call->fault_code);
1378 dcesrv_conn_auth_wait_finished(conn, status);
1382 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1387 * we don't send a reply to a auth3 request.
1390 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1395 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1396 const struct dcerpc_bind *b,
1397 const struct dcerpc_ctx_list *ctx,
1398 struct dcerpc_ack_ctx *ack,
1400 const struct ndr_syntax_id *supported_transfer)
1402 uint32_t if_version;
1403 struct dcesrv_connection_context *context;
1404 const struct dcesrv_interface *iface;
1407 const struct ndr_syntax_id *selected_transfer = NULL;
1412 return NT_STATUS_INTERNAL_ERROR;
1415 return NT_STATUS_INTERNAL_ERROR;
1417 if (ctx->num_transfer_syntaxes < 1) {
1418 return NT_STATUS_INTERNAL_ERROR;
1421 return NT_STATUS_INTERNAL_ERROR;
1423 if (supported_transfer == NULL) {
1424 return NT_STATUS_INTERNAL_ERROR;
1427 switch (ack->result) {
1428 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1429 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1431 * We is already completed.
1433 return NT_STATUS_OK;
1438 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1439 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1441 if_version = ctx->abstract_syntax.if_version;
1442 uuid = ctx->abstract_syntax.uuid;
1444 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1445 if (iface == NULL) {
1446 char *uuid_str = GUID_string(call, &uuid);
1447 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1448 talloc_free(uuid_str);
1450 * We report this only via ack->result
1452 return NT_STATUS_OK;
1455 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1456 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1458 if (validate_only) {
1460 * We report this only via ack->result
1462 return NT_STATUS_OK;
1465 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1467 * we only do NDR encoded dcerpc for now.
1469 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1470 supported_transfer);
1472 selected_transfer = supported_transfer;
1477 context = dcesrv_find_context(call->conn, ctx->context_id);
1478 if (context != NULL) {
1479 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1480 &ctx->abstract_syntax);
1482 return NT_STATUS_RPC_PROTOCOL_ERROR;
1485 if (selected_transfer != NULL) {
1486 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1489 return NT_STATUS_RPC_PROTOCOL_ERROR;
1492 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1493 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1494 ack->syntax = context->transfer_syntax;
1498 * We report this only via ack->result
1500 return NT_STATUS_OK;
1503 if (selected_transfer == NULL) {
1505 * We report this only via ack->result
1507 return NT_STATUS_OK;
1510 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1511 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1513 /* add this context to the list of available context_ids */
1514 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1515 if (context == NULL) {
1516 return NT_STATUS_NO_MEMORY;
1518 context->conn = call->conn;
1519 context->context_id = ctx->context_id;
1520 context->iface = iface;
1521 context->transfer_syntax = *selected_transfer;
1522 context->private_data = NULL;
1523 DLIST_ADD(call->conn->contexts, context);
1524 call->context = context;
1525 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1527 dcesrv_prepare_context_auth(call);
1530 * Multiplex is supported by default
1532 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1534 status = iface->bind(call, iface, if_version);
1535 call->context = NULL;
1536 if (!NT_STATUS_IS_OK(status)) {
1537 /* we don't want to trigger the iface->unbind() hook */
1538 context->iface = NULL;
1539 talloc_free(context);
1541 * We report this only via ack->result
1543 return NT_STATUS_OK;
1546 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1547 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1548 ack->syntax = context->transfer_syntax;
1549 return NT_STATUS_OK;
1552 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1553 const struct dcerpc_bind *b,
1554 struct dcerpc_ack_ctx *ack_ctx_list)
1558 bool validate_only = false;
1559 bool preferred_ndr32;
1562 * Try to negotiate one new presentation context,
1563 * using our preferred transfer syntax.
1565 for (i = 0; i < b->num_contexts; i++) {
1566 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1567 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1569 status = dcesrv_check_or_create_context(call, b, c, a,
1571 call->conn->preferred_transfer);
1572 if (!NT_STATUS_IS_OK(status)) {
1576 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1578 * We managed to negotiate one context.
1582 validate_only = true;
1586 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1587 call->conn->preferred_transfer);
1588 if (preferred_ndr32) {
1592 return NT_STATUS_OK;
1596 * Try to negotiate one new presentation context,
1597 * using NDR 32 as fallback.
1599 for (i = 0; i < b->num_contexts; i++) {
1600 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1601 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1603 status = dcesrv_check_or_create_context(call, b, c, a,
1605 &ndr_transfer_syntax_ndr);
1606 if (!NT_STATUS_IS_OK(status)) {
1610 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1612 * We managed to negotiate one context.
1616 validate_only = true;
1620 return NT_STATUS_OK;
1623 static void dcesrv_alter_done(struct tevent_req *subreq);
1626 handle a alter context request
1628 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1630 struct dcesrv_connection *conn = call->conn;
1632 bool auth_ok = false;
1633 struct ncacn_packet *pkt = &call->ack_pkt;
1634 uint32_t extra_flags = 0;
1635 struct dcesrv_auth *auth = call->auth_state;
1636 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1637 struct tevent_req *subreq = NULL;
1640 if (!call->conn->allow_alter) {
1641 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1644 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1646 call->pkt.u.alter.auth_info.length,
1647 0, /* required flags */
1648 DCERPC_PFC_FLAG_FIRST |
1649 DCERPC_PFC_FLAG_LAST |
1650 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1651 0x08 | /* this is not defined, but should be ignored */
1652 DCERPC_PFC_FLAG_CONC_MPX |
1653 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1654 DCERPC_PFC_FLAG_MAYBE |
1655 DCERPC_PFC_FLAG_OBJECT_UUID);
1656 if (!NT_STATUS_IS_OK(status)) {
1657 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1660 auth_ok = dcesrv_auth_alter(call);
1662 if (call->fault_code != 0) {
1663 return dcesrv_fault_disconnect(call, call->fault_code);
1667 if (call->pkt.u.alter.num_contexts < 1) {
1668 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1671 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1672 call->pkt.u.alter.num_contexts);
1673 if (ack_ctx_list == NULL) {
1674 return NT_STATUS_NO_MEMORY;
1678 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1679 * dcesrv_check_or_create_context()) and do some protocol validation
1680 * and set sane defaults.
1682 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1683 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1684 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1686 if (c->num_transfer_syntaxes == 0) {
1687 return dcesrv_fault_disconnect(call,
1688 DCERPC_NCA_S_PROTO_ERROR);
1691 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1692 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1696 * Try to negotiate one new presentation context.
1698 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1699 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1700 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1702 if (!NT_STATUS_IS_OK(status)) {
1706 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1707 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1708 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1709 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1712 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1713 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1716 /* handle any authentication that is being requested */
1718 if (call->in_auth_info.auth_type != auth->auth_type) {
1719 return dcesrv_fault_disconnect(call,
1720 DCERPC_FAULT_SEC_PKG_ERROR);
1722 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1725 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1726 pkt->auth_length = 0;
1727 pkt->call_id = call->pkt.call_id;
1728 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1729 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1730 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1731 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1732 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1733 pkt->u.alter_resp.secondary_address = "";
1734 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1735 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1736 pkt->u.alter_resp.auth_info = data_blob_null;
1738 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1739 if (!NT_STATUS_IS_OK(status)) {
1740 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1743 if (auth->auth_finished) {
1744 return dcesrv_auth_reply(call);
1747 subreq = gensec_update_send(call, call->event_ctx,
1748 auth->gensec_security,
1749 call->in_auth_info.credentials);
1750 if (subreq == NULL) {
1751 return NT_STATUS_NO_MEMORY;
1753 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1755 return dcesrv_conn_auth_wait_setup(conn);
1758 static void dcesrv_alter_done(struct tevent_req *subreq)
1760 struct dcesrv_call_state *call =
1761 tevent_req_callback_data(subreq,
1762 struct dcesrv_call_state);
1763 struct dcesrv_connection *conn = call->conn;
1766 status = gensec_update_recv(subreq, call,
1767 &call->out_auth_info->credentials);
1768 TALLOC_FREE(subreq);
1770 status = dcesrv_auth_complete(call, status);
1771 if (!NT_STATUS_IS_OK(status)) {
1772 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1773 dcesrv_conn_auth_wait_finished(conn, status);
1777 status = dcesrv_auth_reply(call);
1778 dcesrv_conn_auth_wait_finished(conn, status);
1783 possibly save the call for inspection with ndrdump
1785 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1789 const char *dump_dir;
1790 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1794 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1796 call->context->iface->name,
1797 call->pkt.u.request.opnum,
1799 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1800 DEBUG(0,("RPC SAVED %s\n", fname));
1806 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1808 TALLOC_CTX *frame = talloc_stackframe();
1809 const struct dcesrv_auth *auth = call->auth_state;
1810 const uint32_t bitmask1 = auth->client_hdr_signing ?
1811 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1812 const struct dcerpc_sec_vt_pcontext pcontext = {
1813 .abstract_syntax = call->context->iface->syntax_id,
1814 .transfer_syntax = call->context->transfer_syntax,
1816 const struct dcerpc_sec_vt_header2 header2 =
1817 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1818 enum ndr_err_code ndr_err;
1819 struct dcerpc_sec_verification_trailer *vt = NULL;
1820 NTSTATUS status = NT_STATUS_OK;
1823 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1825 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1827 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1828 status = ndr_map_error2ntstatus(ndr_err);
1832 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1833 &pcontext, &header2);
1835 status = NT_STATUS_ACCESS_DENIED;
1844 handle a dcerpc request packet
1846 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1848 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1849 struct dcesrv_auth *auth = call->auth_state;
1850 enum dcerpc_transport_t transport =
1851 dcerpc_binding_get_transport(endpoint->ep_description);
1852 struct ndr_pull *pull;
1855 if (!call->conn->allow_request) {
1856 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1859 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1860 if (auth->gensec_security != NULL &&
1861 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1862 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1865 if (call->context == NULL) {
1866 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1867 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1870 switch (auth->auth_level) {
1871 case DCERPC_AUTH_LEVEL_NONE:
1872 case DCERPC_AUTH_LEVEL_PACKET:
1873 case DCERPC_AUTH_LEVEL_INTEGRITY:
1874 case DCERPC_AUTH_LEVEL_PRIVACY:
1877 if (!call->context->allow_connect) {
1880 addr = tsocket_address_string(call->conn->remote_address,
1883 DEBUG(2, ("%s: restrict auth_level_connect access "
1884 "to [%s] with auth[type=0x%x,level=0x%x] "
1885 "on [%s] from [%s]\n",
1886 __func__, call->context->iface->name,
1889 derpc_transport_string_by_transport(transport),
1891 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1896 if (auth->auth_level < call->context->min_auth_level) {
1899 addr = tsocket_address_string(call->conn->remote_address, call);
1901 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1902 "to [%s] with auth[type=0x%x,level=0x%x] "
1903 "on [%s] from [%s]\n",
1905 call->context->min_auth_level,
1906 call->context->iface->name,
1909 derpc_transport_string_by_transport(transport),
1911 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1914 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1915 NT_STATUS_HAVE_NO_MEMORY(pull);
1917 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1919 call->ndr_pull = pull;
1921 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1922 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1925 status = dcesrv_check_verification_trailer(call);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 uint32_t faultcode = DCERPC_FAULT_OTHER;
1928 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1929 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1931 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1932 nt_errstr(status)));
1933 return dcesrv_fault(call, faultcode);
1936 /* unravel the NDR for the packet */
1937 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 uint8_t extra_flags = 0;
1940 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1941 /* we got an unknown call */
1942 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1943 call->pkt.u.request.opnum,
1944 call->context->iface->name));
1945 dcesrv_save_call(call, "unknown");
1946 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1948 dcesrv_save_call(call, "pullfail");
1950 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1953 if (pull->offset != pull->data_size) {
1954 dcesrv_save_call(call, "extrabytes");
1955 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1956 pull->data_size - pull->offset));
1959 /* call the dispatch function */
1960 status = call->context->iface->dispatch(call, call, call->r);
1961 if (!NT_STATUS_IS_OK(status)) {
1962 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1963 call->context->iface->name,
1964 call->pkt.u.request.opnum,
1965 dcerpc_errstr(pull, call->fault_code)));
1966 return dcesrv_fault(call, call->fault_code);
1969 /* add the call to the pending list */
1970 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1972 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1973 return NT_STATUS_OK;
1976 return dcesrv_reply(call);
1981 remove the call from the right list when freed
1983 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1985 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1989 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1991 return conn->local_address;
1994 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1996 return conn->remote_address;
2000 process some input to a dcerpc endpoint server.
2002 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2003 struct ncacn_packet *pkt,
2007 struct dcesrv_call_state *call;
2008 struct dcesrv_call_state *existing = NULL;
2010 call = talloc_zero(dce_conn, struct dcesrv_call_state);
2012 data_blob_free(&blob);
2014 return NT_STATUS_NO_MEMORY;
2016 call->conn = dce_conn;
2017 call->event_ctx = dce_conn->event_ctx;
2018 call->msg_ctx = dce_conn->msg_ctx;
2019 call->state_flags = call->conn->state_flags;
2020 call->time = timeval_current();
2021 call->list = DCESRV_LIST_NONE;
2023 talloc_steal(call, pkt);
2024 talloc_steal(call, blob.data);
2027 call->auth_state = dce_conn->default_auth_state;
2029 talloc_set_destructor(call, dcesrv_call_dequeue);
2031 if (call->conn->allow_bind) {
2033 * Only one bind is possible per connection
2035 call->conn->allow_bind = false;
2036 return dcesrv_bind(call);
2039 /* we have to check the signing here, before combining the
2041 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2042 if (!call->conn->allow_request) {
2043 return dcesrv_fault_disconnect(call,
2044 DCERPC_NCA_S_PROTO_ERROR);
2047 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2049 call->pkt.u.request.stub_and_verifier.length,
2050 0, /* required_flags */
2051 DCERPC_PFC_FLAG_FIRST |
2052 DCERPC_PFC_FLAG_LAST |
2053 DCERPC_PFC_FLAG_PENDING_CANCEL |
2054 0x08 | /* this is not defined, but should be ignored */
2055 DCERPC_PFC_FLAG_CONC_MPX |
2056 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2057 DCERPC_PFC_FLAG_MAYBE |
2058 DCERPC_PFC_FLAG_OBJECT_UUID);
2059 if (!NT_STATUS_IS_OK(status)) {
2060 return dcesrv_fault_disconnect(call,
2061 DCERPC_NCA_S_PROTO_ERROR);
2064 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2066 * We don't use dcesrv_fault_disconnect()
2067 * here, because we don't want to set
2068 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2070 * Note that we don't check against the negotiated
2071 * max_recv_frag, but a hard coded value.
2073 dcesrv_call_disconnect_after(call,
2074 "dcesrv_auth_request - frag_length too large");
2075 return dcesrv_fault(call,
2076 DCERPC_NCA_S_PROTO_ERROR);
2079 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2080 if (dce_conn->pending_call_list != NULL) {
2082 * concurrent requests are only allowed
2083 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2085 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2086 dcesrv_call_disconnect_after(call,
2087 "dcesrv_auth_request - "
2088 "existing pending call without CONN_MPX");
2089 return dcesrv_fault(call,
2090 DCERPC_NCA_S_PROTO_ERROR);
2093 /* only one request is possible in the fragmented list */
2094 if (dce_conn->incoming_fragmented_call_list != NULL) {
2095 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2097 * Without DCERPC_PFC_FLAG_CONC_MPX
2098 * we need to return the FAULT on the
2099 * already existing call.
2101 * This is important to get the
2102 * call_id and context_id right.
2105 call = dce_conn->incoming_fragmented_call_list;
2107 dcesrv_call_disconnect_after(call,
2108 "dcesrv_auth_request - "
2109 "existing fragmented call");
2110 return dcesrv_fault(call,
2111 DCERPC_NCA_S_PROTO_ERROR);
2113 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2114 return dcesrv_fault_disconnect(call,
2115 DCERPC_FAULT_NO_CALL_ACTIVE);
2117 call->context = dcesrv_find_context(call->conn,
2118 call->pkt.u.request.context_id);
2119 if (call->context == NULL) {
2120 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2121 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2124 const struct dcerpc_request *nr = &call->pkt.u.request;
2125 const struct dcerpc_request *er = NULL;
2128 existing = dcesrv_find_fragmented_call(dce_conn,
2130 if (existing == NULL) {
2131 dcesrv_call_disconnect_after(call,
2132 "dcesrv_auth_request - "
2133 "no existing fragmented call");
2134 return dcesrv_fault(call,
2135 DCERPC_NCA_S_PROTO_ERROR);
2137 er = &existing->pkt.u.request;
2139 if (call->pkt.ptype != existing->pkt.ptype) {
2140 /* trying to play silly buggers are we? */
2141 return dcesrv_fault_disconnect(existing,
2142 DCERPC_NCA_S_PROTO_ERROR);
2144 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2147 return dcesrv_fault_disconnect(existing,
2148 DCERPC_NCA_S_PROTO_ERROR);
2150 if (nr->context_id != er->context_id) {
2151 return dcesrv_fault_disconnect(existing,
2152 DCERPC_NCA_S_PROTO_ERROR);
2154 if (nr->opnum != er->opnum) {
2155 return dcesrv_fault_disconnect(existing,
2156 DCERPC_NCA_S_PROTO_ERROR);
2161 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2163 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2165 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2166 payload_offset += 16;
2169 ok = dcesrv_auth_pkt_pull(call, &blob,
2170 0, /* required_flags */
2171 DCERPC_PFC_FLAG_FIRST |
2172 DCERPC_PFC_FLAG_LAST |
2173 DCERPC_PFC_FLAG_PENDING_CANCEL |
2174 0x08 | /* this is not defined, but should be ignored */
2175 DCERPC_PFC_FLAG_CONC_MPX |
2176 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2177 DCERPC_PFC_FLAG_MAYBE |
2178 DCERPC_PFC_FLAG_OBJECT_UUID,
2180 &call->pkt.u.request.stub_and_verifier);
2183 * We don't use dcesrv_fault_disconnect()
2184 * here, because we don't want to set
2185 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2187 dcesrv_call_disconnect_after(call,
2188 "dcesrv_auth_request - failed");
2189 if (call->fault_code == 0) {
2190 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2192 return dcesrv_fault(call, call->fault_code);
2196 /* see if this is a continued packet */
2197 if (existing != NULL) {
2198 struct dcerpc_request *er = &existing->pkt.u.request;
2199 const struct dcerpc_request *nr = &call->pkt.u.request;
2205 * Up to 4 MByte are allowed by all fragments
2207 available = dce_conn->max_total_request_size;
2208 if (er->stub_and_verifier.length > available) {
2209 dcesrv_call_disconnect_after(existing,
2210 "dcesrv_auth_request - existing payload too large");
2211 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2213 available -= er->stub_and_verifier.length;
2214 if (nr->alloc_hint > available) {
2215 dcesrv_call_disconnect_after(existing,
2216 "dcesrv_auth_request - alloc hint too large");
2217 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2219 if (nr->stub_and_verifier.length > available) {
2220 dcesrv_call_disconnect_after(existing,
2221 "dcesrv_auth_request - new payload too large");
2222 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2224 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2225 /* allocate at least 1 byte */
2226 alloc_hint = MAX(alloc_hint, 1);
2227 alloc_size = er->stub_and_verifier.length +
2228 nr->stub_and_verifier.length;
2229 alloc_size = MAX(alloc_size, alloc_hint);
2231 er->stub_and_verifier.data =
2232 talloc_realloc(existing,
2233 er->stub_and_verifier.data,
2234 uint8_t, alloc_size);
2235 if (er->stub_and_verifier.data == NULL) {
2237 return dcesrv_fault_with_flags(existing,
2238 DCERPC_FAULT_OUT_OF_RESOURCES,
2239 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2241 memcpy(er->stub_and_verifier.data +
2242 er->stub_and_verifier.length,
2243 nr->stub_and_verifier.data,
2244 nr->stub_and_verifier.length);
2245 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2247 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2253 /* this may not be the last pdu in the chain - if its isn't then
2254 just put it on the incoming_fragmented_call_list and wait for the rest */
2255 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2256 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2258 * Up to 4 MByte are allowed by all fragments
2260 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2261 dcesrv_call_disconnect_after(call,
2262 "dcesrv_auth_request - initial alloc hint too large");
2263 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2265 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2266 return NT_STATUS_OK;
2269 /* This removes any fragments we may have had stashed away */
2270 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2272 switch (call->pkt.ptype) {
2273 case DCERPC_PKT_BIND:
2274 status = dcesrv_bind_nak(call,
2275 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2277 case DCERPC_PKT_AUTH3:
2278 status = dcesrv_auth3(call);
2280 case DCERPC_PKT_ALTER:
2281 status = dcesrv_alter(call);
2283 case DCERPC_PKT_REQUEST:
2284 status = dcesrv_request(call);
2286 case DCERPC_PKT_CO_CANCEL:
2287 case DCERPC_PKT_ORPHANED:
2289 * Window just ignores CO_CANCEL and ORPHANED,
2292 status = NT_STATUS_OK;
2295 case DCERPC_PKT_BIND_ACK:
2296 case DCERPC_PKT_BIND_NAK:
2297 case DCERPC_PKT_ALTER_RESP:
2298 case DCERPC_PKT_RESPONSE:
2299 case DCERPC_PKT_FAULT:
2300 case DCERPC_PKT_SHUTDOWN:
2302 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2306 /* if we are going to be sending a reply then add
2307 it to the list of pending calls. We add it to the end to keep the call
2308 list in the order we will answer */
2309 if (!NT_STATUS_IS_OK(status)) {
2316 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2317 struct loadparm_context *lp_ctx,
2318 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2321 struct dcesrv_context *dce_ctx;
2324 if (!endpoint_servers) {
2325 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2326 return NT_STATUS_INTERNAL_ERROR;
2329 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2330 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2332 if (uid_wrapper_enabled()) {
2333 setenv("UID_WRAPPER_MYUID", "1", 1);
2335 dce_ctx->initial_euid = geteuid();
2336 if (uid_wrapper_enabled()) {
2337 unsetenv("UID_WRAPPER_MYUID");
2340 dce_ctx->endpoint_list = NULL;
2341 dce_ctx->lp_ctx = lp_ctx;
2342 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2343 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2344 dce_ctx->broken_connections = NULL;
2346 for (i=0;endpoint_servers[i];i++) {
2347 const struct dcesrv_endpoint_server *ep_server;
2349 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2351 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2352 return NT_STATUS_INTERNAL_ERROR;
2355 status = ep_server->init_server(dce_ctx, ep_server);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2358 nt_errstr(status)));
2363 *_dce_ctx = dce_ctx;
2364 return NT_STATUS_OK;
2367 /* the list of currently registered DCERPC endpoint servers.
2369 static struct ep_server {
2370 struct dcesrv_endpoint_server *ep_server;
2371 } *ep_servers = NULL;
2372 static int num_ep_servers;
2375 register a DCERPC endpoint server.
2377 The 'name' can be later used by other backends to find the operations
2378 structure for this backend.
2381 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2384 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2385 /* its already registered! */
2386 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2388 return NT_STATUS_OBJECT_NAME_COLLISION;
2391 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2393 smb_panic("out of memory in dcerpc_register");
2396 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2397 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2401 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2404 return NT_STATUS_OK;
2408 return the operations structure for a named backend of the specified type
2410 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2414 for (i=0;i<num_ep_servers;i++) {
2415 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2416 return ep_servers[i].ep_server;
2423 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2425 static bool initialized;
2426 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2427 STATIC_dcerpc_server_MODULES_PROTO;
2428 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2429 init_module_fn *shared_init;
2436 shared_init = load_samba_modules(NULL, "dcerpc_server");
2438 run_init_functions(NULL, static_init);
2439 run_init_functions(NULL, shared_init);
2441 talloc_free(shared_init);
2445 return the DCERPC module version, and the size of some critical types
2446 This can be used by endpoint server modules to either detect compilation errors, or provide
2447 multiple implementations for different smbd compilation options in one module
2449 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2451 static const struct dcesrv_critical_sizes critical_sizes = {
2452 DCERPC_MODULE_VERSION,
2453 sizeof(struct dcesrv_context),
2454 sizeof(struct dcesrv_endpoint),
2455 sizeof(struct dcesrv_endpoint_server),
2456 sizeof(struct dcesrv_interface),
2457 sizeof(struct dcesrv_if_list),
2458 sizeof(struct dcesrv_connection),
2459 sizeof(struct dcesrv_call_state),
2460 sizeof(struct dcesrv_auth),
2461 sizeof(struct dcesrv_handle)
2464 return &critical_sizes;
2467 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2469 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2470 struct stream_connection *srv_conn;
2471 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2472 struct stream_connection);
2474 dce_conn->wait_send = NULL;
2475 dce_conn->wait_recv = NULL;
2476 dce_conn->wait_private = NULL;
2478 dce_conn->allow_bind = false;
2479 dce_conn->allow_auth3 = false;
2480 dce_conn->allow_alter = false;
2481 dce_conn->allow_request = false;
2483 dce_conn->default_auth_state->auth_invalid = true;
2485 if (dce_conn->pending_call_list == NULL) {
2486 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2488 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2489 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2493 if (dce_conn->terminate != NULL) {
2497 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2499 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2500 if (dce_conn->terminate == NULL) {
2501 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2503 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2506 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2508 struct dcesrv_connection *cur, *next;
2510 next = dce_ctx->broken_connections;
2511 while (next != NULL) {
2515 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2516 struct dcesrv_connection_context *context_cur, *context_next;
2518 context_next = cur->contexts;
2519 while (context_next != NULL) {
2520 context_cur = context_next;
2521 context_next = context_cur->next;
2523 dcesrv_connection_context_destructor(context_cur);
2527 dcesrv_terminate_connection(cur, cur->terminate);
2531 /* We need this include to be able to compile on some plateforms
2532 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2534 * It has to be that deep because otherwise we have a conflict on
2535 * const struct dcesrv_interface declaration.
2536 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2537 * which conflict with the bind used before.
2539 #include "system/network.h"
2541 struct dcesrv_sock_reply_state {
2542 struct dcesrv_connection *dce_conn;
2543 struct dcesrv_call_state *call;
2547 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2548 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2550 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2552 struct dcesrv_call_state *call;
2554 call = dce_conn->call_list;
2555 if (!call || !call->replies) {
2559 while (call->replies) {
2560 struct data_blob_list_item *rep = call->replies;
2561 struct dcesrv_sock_reply_state *substate;
2562 struct tevent_req *subreq;
2564 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2566 dcesrv_terminate_connection(dce_conn, "no memory");
2570 substate->dce_conn = dce_conn;
2571 substate->call = NULL;
2573 DLIST_REMOVE(call->replies, rep);
2575 if (call->replies == NULL && call->terminate_reason == NULL) {
2576 substate->call = call;
2579 substate->iov.iov_base = (void *) rep->blob.data;
2580 substate->iov.iov_len = rep->blob.length;
2582 subreq = tstream_writev_queue_send(substate,
2583 dce_conn->event_ctx,
2585 dce_conn->send_queue,
2588 dcesrv_terminate_connection(dce_conn, "no memory");
2591 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2595 if (call->terminate_reason != NULL) {
2596 struct tevent_req *subreq;
2598 subreq = tevent_queue_wait_send(call,
2599 dce_conn->event_ctx,
2600 dce_conn->send_queue);
2602 dcesrv_terminate_connection(dce_conn, __location__);
2605 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2609 DLIST_REMOVE(call->conn->call_list, call);
2610 call->list = DCESRV_LIST_NONE;
2613 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2615 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2616 struct dcesrv_sock_reply_state);
2620 struct dcesrv_call_state *call = substate->call;
2622 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2623 TALLOC_FREE(subreq);
2625 status = map_nt_error_from_unix_common(sys_errno);
2626 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2630 talloc_free(substate);
2636 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2638 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2640 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2641 struct dcesrv_call_state);
2645 /* make sure we stop send queue before removing subreq */
2646 tevent_queue_stop(call->conn->send_queue);
2648 ok = tevent_queue_wait_recv(subreq);
2649 TALLOC_FREE(subreq);
2651 dcesrv_terminate_connection(call->conn, __location__);
2655 /* disconnect after 200 usecs */
2656 tv = timeval_current_ofs_usec(200);
2657 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2658 if (subreq == NULL) {
2659 dcesrv_terminate_connection(call->conn, __location__);
2662 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2666 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2668 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2669 struct dcesrv_call_state);
2672 ok = tevent_wakeup_recv(subreq);
2673 TALLOC_FREE(subreq);
2675 dcesrv_terminate_connection(call->conn, __location__);
2679 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2682 struct dcesrv_socket_context {
2683 const struct dcesrv_endpoint *endpoint;
2684 struct dcesrv_context *dcesrv_ctx;
2688 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2690 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2693 struct dcesrv_socket_context *dcesrv_sock =
2694 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2695 enum dcerpc_transport_t transport =
2696 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2697 struct dcesrv_connection *dcesrv_conn = NULL;
2699 struct tevent_req *subreq;
2700 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2702 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2704 if (!srv_conn->session_info) {
2705 status = auth_anonymous_session_info(srv_conn,
2707 &srv_conn->session_info);
2708 if (!NT_STATUS_IS_OK(status)) {
2709 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2710 nt_errstr(status)));
2711 stream_terminate_connection(srv_conn, nt_errstr(status));
2717 * This fills in dcesrv_conn->endpoint with the endpoint
2718 * associated with the socket. From this point on we know
2719 * which (group of) services we are handling, but not the
2720 * specific interface.
2723 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2725 dcesrv_sock->endpoint,
2726 srv_conn->session_info,
2727 srv_conn->event.ctx,
2729 srv_conn->server_id,
2730 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2732 if (!NT_STATUS_IS_OK(status)) {
2733 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2734 nt_errstr(status)));
2735 stream_terminate_connection(srv_conn, nt_errstr(status));
2739 dcesrv_conn->transport.private_data = srv_conn;
2740 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2742 TALLOC_FREE(srv_conn->event.fde);
2744 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2745 if (!dcesrv_conn->send_queue) {
2746 status = NT_STATUS_NO_MEMORY;
2747 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2748 nt_errstr(status)));
2749 stream_terminate_connection(srv_conn, nt_errstr(status));
2753 if (transport == NCACN_NP) {
2754 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2755 &srv_conn->tstream);
2757 ret = tstream_bsd_existing_socket(dcesrv_conn,
2758 socket_get_fd(srv_conn->socket),
2759 &dcesrv_conn->stream);
2761 status = map_nt_error_from_unix_common(errno);
2762 DEBUG(0, ("dcesrv_sock_accept: "
2763 "failed to setup tstream: %s\n",
2764 nt_errstr(status)));
2765 stream_terminate_connection(srv_conn, nt_errstr(status));
2768 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2771 dcesrv_conn->local_address = srv_conn->local_address;
2772 dcesrv_conn->remote_address = srv_conn->remote_address;
2774 if (transport == NCALRPC) {
2779 sock_fd = socket_get_fd(srv_conn->socket);
2780 if (sock_fd == -1) {
2781 stream_terminate_connection(
2782 srv_conn, "socket_get_fd failed\n");
2786 ret = getpeereid(sock_fd, &uid, &gid);
2788 status = map_nt_error_from_unix_common(errno);
2789 DEBUG(0, ("dcesrv_sock_accept: "
2790 "getpeereid() failed for NCALRPC: %s\n",
2791 nt_errstr(status)));
2792 stream_terminate_connection(srv_conn, nt_errstr(status));
2795 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2796 struct tsocket_address *r = NULL;
2798 ret = tsocket_address_unix_from_path(dcesrv_conn,
2799 AS_SYSTEM_MAGIC_PATH_TOKEN,
2802 status = map_nt_error_from_unix_common(errno);
2803 DEBUG(0, ("dcesrv_sock_accept: "
2804 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2805 nt_errstr(status)));
2806 stream_terminate_connection(srv_conn, nt_errstr(status));
2809 dcesrv_conn->remote_address = r;
2813 srv_conn->private_data = dcesrv_conn;
2815 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2816 dcesrv_conn->event_ctx,
2817 dcesrv_conn->stream);
2819 status = NT_STATUS_NO_MEMORY;
2820 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2821 nt_errstr(status)));
2822 stream_terminate_connection(srv_conn, nt_errstr(status));
2825 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2830 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2832 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2834 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2835 struct dcesrv_connection);
2836 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2837 struct ncacn_packet *pkt;
2841 if (dce_conn->terminate) {
2843 * if the current connection is broken
2844 * we need to clean it up before any other connection
2846 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2847 dcesrv_cleanup_broken_connections(dce_ctx);
2851 dcesrv_cleanup_broken_connections(dce_ctx);
2853 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2855 TALLOC_FREE(subreq);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2861 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2862 if (!NT_STATUS_IS_OK(status)) {
2863 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2868 * This is used to block the connection during
2869 * pending authentication.
2871 if (dce_conn->wait_send != NULL) {
2872 subreq = dce_conn->wait_send(dce_conn,
2873 dce_conn->event_ctx,
2874 dce_conn->wait_private);
2876 status = NT_STATUS_NO_MEMORY;
2877 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2880 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2884 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2885 dce_conn->event_ctx,
2888 status = NT_STATUS_NO_MEMORY;
2889 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2892 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2895 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2897 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2898 struct dcesrv_connection);
2899 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2902 if (dce_conn->terminate) {
2904 * if the current connection is broken
2905 * we need to clean it up before any other connection
2907 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2908 dcesrv_cleanup_broken_connections(dce_ctx);
2912 dcesrv_cleanup_broken_connections(dce_ctx);
2914 status = dce_conn->wait_recv(subreq);
2915 dce_conn->wait_send = NULL;
2916 dce_conn->wait_recv = NULL;
2917 dce_conn->wait_private = NULL;
2918 TALLOC_FREE(subreq);
2919 if (!NT_STATUS_IS_OK(status)) {
2920 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2924 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2925 dce_conn->event_ctx,
2928 status = NT_STATUS_NO_MEMORY;
2929 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2932 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2935 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2937 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2938 struct dcesrv_connection);
2939 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2942 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2944 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2945 struct dcesrv_connection);
2946 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2950 static const struct stream_server_ops dcesrv_stream_ops = {
2952 .accept_connection = dcesrv_sock_accept,
2953 .recv_handler = dcesrv_sock_recv,
2954 .send_handler = dcesrv_sock_send,
2957 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2958 struct loadparm_context *lp_ctx,
2959 struct dcesrv_endpoint *e,
2960 struct tevent_context *event_ctx,
2961 const struct model_ops *model_ops,
2962 void *process_context)
2964 struct dcesrv_socket_context *dcesrv_sock;
2967 const char *endpoint;
2969 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2970 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2972 /* remember the endpoint of this socket */
2973 dcesrv_sock->endpoint = e;
2974 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2976 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2978 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2979 model_ops, &dcesrv_stream_ops,
2980 "unix", endpoint, &port,
2981 lpcfg_socket_options(lp_ctx),
2982 dcesrv_sock, process_context);
2983 if (!NT_STATUS_IS_OK(status)) {
2984 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2985 endpoint, nt_errstr(status)));
2991 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2992 struct loadparm_context *lp_ctx,
2993 struct dcesrv_endpoint *e,
2994 struct tevent_context *event_ctx,
2995 const struct model_ops *model_ops,
2996 void *process_context)
2998 struct dcesrv_socket_context *dcesrv_sock;
3002 const char *endpoint;
3004 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3006 if (endpoint == NULL) {
3008 * No identifier specified: use DEFAULT.
3010 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
3011 * no endpoint and let the epmapper worry about it.
3013 endpoint = "DEFAULT";
3014 status = dcerpc_binding_set_string_option(e->ep_description,
3017 if (!NT_STATUS_IS_OK(status)) {
3018 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
3019 nt_errstr(status)));
3024 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
3027 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3028 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3030 /* remember the endpoint of this socket */
3031 dcesrv_sock->endpoint = e;
3032 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3034 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3035 model_ops, &dcesrv_stream_ops,
3036 "unix", full_path, &port,
3037 lpcfg_socket_options(lp_ctx),
3038 dcesrv_sock, process_context);
3039 if (!NT_STATUS_IS_OK(status)) {
3040 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3041 endpoint, full_path, nt_errstr(status)));
3046 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3047 struct loadparm_context *lp_ctx,
3048 struct dcesrv_endpoint *e,
3049 struct tevent_context *event_ctx,
3050 const struct model_ops *model_ops,
3051 void *process_context)
3053 struct dcesrv_socket_context *dcesrv_sock;
3055 const char *endpoint;
3057 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3058 if (endpoint == NULL) {
3059 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3060 return NT_STATUS_INVALID_PARAMETER;
3063 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3064 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3066 /* remember the endpoint of this socket */
3067 dcesrv_sock->endpoint = e;
3068 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3070 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3071 model_ops, &dcesrv_stream_ops,
3073 dcesrv_sock, process_context);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3076 endpoint, nt_errstr(status)));
3080 return NT_STATUS_OK;
3084 add a socket address to the list of events, one event per dcerpc endpoint
3086 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3087 struct dcesrv_endpoint *e,
3088 struct tevent_context *event_ctx,
3089 const struct model_ops *model_ops,
3090 const char *address,
3091 void *process_context)
3093 struct dcesrv_socket_context *dcesrv_sock;
3096 const char *endpoint;
3099 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3100 if (endpoint != NULL) {
3101 port = atoi(endpoint);
3104 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3105 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3107 /* remember the endpoint of this socket */
3108 dcesrv_sock->endpoint = e;
3109 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3111 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3112 model_ops, &dcesrv_stream_ops,
3113 "ip", address, &port,
3114 lpcfg_socket_options(dce_ctx->lp_ctx),
3115 dcesrv_sock, process_context);
3116 if (!NT_STATUS_IS_OK(status)) {
3117 struct dcesrv_if_list *iface;
3118 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3120 for (iface = e->interface_list; iface; iface = iface->next) {
3121 DEBUGADD(0, ("%s ", iface->iface.name));
3123 DEBUGADD(0, ("failed - %s",
3124 nt_errstr(status)));
3128 snprintf(port_str, sizeof(port_str), "%u", port);
3130 status = dcerpc_binding_set_string_option(e->ep_description,
3131 "endpoint", port_str);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3134 port_str, nt_errstr(status)));
3137 struct dcesrv_if_list *iface;
3138 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3139 address, port_str));
3140 for (iface = e->interface_list; iface; iface = iface->next) {
3141 DEBUGADD(4, ("%s ", iface->iface.name));
3143 DEBUGADD(4, ("\n"));
3146 return NT_STATUS_OK;
3149 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3151 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3152 struct loadparm_context *lp_ctx,
3153 struct dcesrv_endpoint *e,
3154 struct tevent_context *event_ctx,
3155 const struct model_ops *model_ops,
3156 void *process_context)
3160 /* Add TCP/IP sockets */
3161 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3164 struct interface *ifaces;
3166 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3168 num_interfaces = iface_list_count(ifaces);
3169 for(i = 0; i < num_interfaces; i++) {
3170 const char *address = iface_list_n_ip(ifaces, i);
3171 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3174 NT_STATUS_NOT_OK_RETURN(status);
3179 size_t num_binds = 0;
3180 wcard = iface_list_wildcard(dce_ctx);
3181 NT_STATUS_HAVE_NO_MEMORY(wcard);
3182 for (i=0; wcard[i]; i++) {
3183 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3184 model_ops, wcard[i],
3186 if (NT_STATUS_IS_OK(status)) {
3191 if (num_binds == 0) {
3192 return NT_STATUS_INVALID_PARAMETER_MIX;
3196 return NT_STATUS_OK;
3199 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3200 struct loadparm_context *lp_ctx,
3201 struct dcesrv_endpoint *e,
3202 struct tevent_context *event_ctx,
3203 const struct model_ops *model_ops,
3204 void *process_context)
3206 enum dcerpc_transport_t transport =
3207 dcerpc_binding_get_transport(e->ep_description);
3209 switch (transport) {
3210 case NCACN_UNIX_STREAM:
3211 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3212 model_ops, process_context);
3215 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3216 model_ops, process_context);
3219 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3220 model_ops, process_context);
3223 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3224 model_ops, process_context);
3227 return NT_STATUS_NOT_SUPPORTED;
3233 * retrieve credentials from a dce_call
3235 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3237 struct dcesrv_auth *auth = dce_call->auth_state;
3238 return auth->session_info->credentials;
3242 * returns true if this is an authenticated call
3244 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3246 struct dcesrv_auth *auth = dce_call->auth_state;
3247 enum security_user_level level;
3248 level = security_session_user_level(auth->session_info, NULL);
3249 return level >= SECURITY_USER;
3253 * retrieve account_name for a dce_call
3255 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3257 struct dcesrv_auth *auth = dce_call->auth_state;
3258 return auth->session_info->info->account_name;
3262 * retrieve session_info from a dce_call
3264 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3266 struct dcesrv_auth *auth = dce_call->auth_state;
3267 return auth->session_info;
3271 * retrieve auth type/level from a dce_call
3273 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3274 enum dcerpc_AuthType *auth_type,
3275 enum dcerpc_AuthLevel *auth_level)
3277 struct dcesrv_auth *auth = dce_call->auth_state;
3279 if (auth_type != NULL) {
3280 *auth_type = auth->auth_type;
3282 if (auth_level != NULL) {
3283 *auth_level = auth->auth_level;