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);
535 connect to a dcerpc endpoint
537 static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
539 const struct dcesrv_endpoint *ep,
540 struct auth_session_info *session_info,
541 struct tevent_context *event_ctx,
542 struct imessaging_context *msg_ctx,
543 struct server_id server_id,
544 uint32_t state_flags,
545 struct dcesrv_connection **_p)
547 enum dcerpc_transport_t transport =
548 dcerpc_binding_get_transport(ep->ep_description);
549 struct dcesrv_connection *p;
552 return NT_STATUS_ACCESS_DENIED;
555 p = talloc_zero(mem_ctx, struct dcesrv_connection);
556 NT_STATUS_HAVE_NO_MEMORY(p);
558 if (!talloc_reference(p, session_info)) {
560 return NT_STATUS_NO_MEMORY;
563 p->dce_ctx = dce_ctx;
565 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
566 p->event_ctx = event_ctx;
567 p->msg_ctx = msg_ctx;
568 p->server_id = server_id;
569 p->state_flags = state_flags;
570 p->allow_bind = true;
571 p->max_recv_frag = 5840;
572 p->max_xmit_frag = 5840;
573 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
575 p->auth_state.session_info = session_info;
578 p->auth_state.session_key_fn = dcesrv_remote_session_key;
581 case NCACN_UNIX_STREAM:
582 p->auth_state.session_key_fn = dcesrv_local_fixed_session_key;
586 * All other's get a NULL pointer, which
587 * results in NT_STATUS_NO_USER_SESSION_KEY
593 * For now we only support NDR32.
595 p->preferred_transfer = &ndr_transfer_syntax_ndr;
602 move a call from an existing linked list to the specified list. This
603 prevents bugs where we forget to remove the call from a previous
606 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
607 enum dcesrv_call_list list)
609 switch (call->list) {
610 case DCESRV_LIST_NONE:
612 case DCESRV_LIST_CALL_LIST:
613 DLIST_REMOVE(call->conn->call_list, call);
615 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
616 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
618 case DCESRV_LIST_PENDING_CALL_LIST:
619 DLIST_REMOVE(call->conn->pending_call_list, call);
624 case DCESRV_LIST_NONE:
626 case DCESRV_LIST_CALL_LIST:
627 DLIST_ADD_END(call->conn->call_list, call);
629 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
630 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
632 case DCESRV_LIST_PENDING_CALL_LIST:
633 DLIST_ADD_END(call->conn->pending_call_list, call);
638 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
641 if (call->conn->terminate != NULL) {
645 call->conn->allow_bind = false;
646 call->conn->allow_alter = false;
647 call->conn->allow_auth3 = false;
648 call->conn->allow_request = false;
650 call->terminate_reason = talloc_strdup(call, reason);
651 if (call->terminate_reason == NULL) {
652 call->terminate_reason = __location__;
657 return a dcerpc bind_nak
659 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
661 struct ncacn_packet pkt;
662 struct dcerpc_bind_nak_version version;
663 struct data_blob_list_item *rep;
665 static const uint8_t _pad[3] = { 0, };
668 * We add the call to the pending_call_list
669 * in order to defer the termination.
671 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
673 /* setup a bind_nak */
674 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
676 pkt.call_id = call->pkt.call_id;
677 pkt.ptype = DCERPC_PKT_BIND_NAK;
678 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
679 pkt.u.bind_nak.reject_reason = reason;
680 version.rpc_vers = 5;
681 version.rpc_vers_minor = 0;
682 pkt.u.bind_nak.num_versions = 1;
683 pkt.u.bind_nak.versions = &version;
684 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
686 rep = talloc_zero(call, struct data_blob_list_item);
688 return NT_STATUS_NO_MEMORY;
691 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
692 if (!NT_STATUS_IS_OK(status)) {
696 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
698 DLIST_ADD_END(call->replies, rep);
699 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
701 if (call->conn->call_list && call->conn->call_list->replies) {
702 if (call->conn->transport.report_output_data) {
703 call->conn->transport.report_output_data(call->conn);
710 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
714 * We add the call to the pending_call_list
715 * in order to defer the termination.
717 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
719 return dcesrv_fault_with_flags(call, fault_code,
720 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
723 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
725 DLIST_REMOVE(c->conn->contexts, c);
727 if (c->iface && c->iface->unbind) {
728 c->iface->unbind(c, c->iface);
735 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
737 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
738 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
739 enum dcerpc_transport_t transport =
740 dcerpc_binding_get_transport(endpoint->ep_description);
741 struct dcesrv_connection_context *context = dce_call->context;
742 const struct dcesrv_interface *iface = context->iface;
744 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
746 if (transport == NCALRPC) {
747 context->allow_connect = true;
752 * allow overwrite per interface
753 * allow dcerpc auth level connect:<interface>
755 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
756 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
757 "allow dcerpc auth level connect",
759 context->allow_connect);
762 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
763 const struct dcesrv_interface *iface)
765 if (dce_call->context == NULL) {
766 return NT_STATUS_INTERNAL_ERROR;
770 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
771 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
773 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
777 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
778 const struct dcesrv_interface *iface)
780 if (dce_call->context == NULL) {
781 return NT_STATUS_INTERNAL_ERROR;
784 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
788 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
789 const struct dcesrv_interface *iface)
791 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
792 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
793 enum dcerpc_transport_t transport =
794 dcerpc_binding_get_transport(endpoint->ep_description);
795 struct dcesrv_connection_context *context = dce_call->context;
797 if (context == NULL) {
798 return NT_STATUS_INTERNAL_ERROR;
801 if (transport == NCALRPC) {
802 context->allow_connect = true;
807 * allow overwrite per interface
808 * allow dcerpc auth level connect:<interface>
810 context->allow_connect = false;
811 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
812 "allow dcerpc auth level connect",
814 context->allow_connect);
818 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
819 const struct dcesrv_interface *iface)
821 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
822 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
823 enum dcerpc_transport_t transport =
824 dcerpc_binding_get_transport(endpoint->ep_description);
825 struct dcesrv_connection_context *context = dce_call->context;
827 if (context == NULL) {
828 return NT_STATUS_INTERNAL_ERROR;
831 if (transport == NCALRPC) {
832 context->allow_connect = true;
837 * allow overwrite per interface
838 * allow dcerpc auth level connect:<interface>
840 context->allow_connect = true;
841 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
842 "allow dcerpc auth level connect",
844 context->allow_connect);
848 struct dcesrv_conn_auth_wait_context {
849 struct tevent_req *req;
854 struct dcesrv_conn_auth_wait_state {
858 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
859 struct tevent_context *ev,
862 struct dcesrv_conn_auth_wait_context *auth_wait =
863 talloc_get_type_abort(private_data,
864 struct dcesrv_conn_auth_wait_context);
865 struct tevent_req *req = NULL;
866 struct dcesrv_conn_auth_wait_state *state = NULL;
868 req = tevent_req_create(mem_ctx, &state,
869 struct dcesrv_conn_auth_wait_state);
873 auth_wait->req = req;
875 tevent_req_defer_callback(req, ev);
877 if (!auth_wait->done) {
881 if (tevent_req_nterror(req, auth_wait->status)) {
882 return tevent_req_post(req, ev);
885 tevent_req_done(req);
886 return tevent_req_post(req, ev);
889 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
891 return tevent_req_simple_recv_ntstatus(req);
894 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
896 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
898 if (conn->wait_send != NULL) {
899 return NT_STATUS_INTERNAL_ERROR;
902 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
903 if (auth_wait == NULL) {
904 return NT_STATUS_NO_MEMORY;
907 conn->wait_private = auth_wait;
908 conn->wait_send = dcesrv_conn_auth_wait_send;
909 conn->wait_recv = dcesrv_conn_auth_wait_recv;
913 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
916 struct dcesrv_conn_auth_wait_context *auth_wait =
917 talloc_get_type_abort(conn->wait_private,
918 struct dcesrv_conn_auth_wait_context);
920 auth_wait->done = true;
921 auth_wait->status = status;
923 if (auth_wait->req == NULL) {
927 if (tevent_req_nterror(auth_wait->req, status)) {
931 tevent_req_done(auth_wait->req);
934 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
936 static void dcesrv_bind_done(struct tevent_req *subreq);
939 handle a bind request
941 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
943 struct dcesrv_connection *conn = call->conn;
944 struct ncacn_packet *pkt = &call->ack_pkt;
946 uint32_t extra_flags = 0;
947 uint16_t max_req = 0;
948 uint16_t max_rep = 0;
949 const char *ep_prefix = "";
950 const char *endpoint = NULL;
951 struct dcesrv_auth *auth = call->auth_state;
952 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
953 struct dcerpc_ack_ctx *ack_features = NULL;
954 struct tevent_req *subreq = NULL;
957 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
959 call->pkt.u.bind.auth_info.length,
960 0, /* required flags */
961 DCERPC_PFC_FLAG_FIRST |
962 DCERPC_PFC_FLAG_LAST |
963 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
964 0x08 | /* this is not defined, but should be ignored */
965 DCERPC_PFC_FLAG_CONC_MPX |
966 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
967 DCERPC_PFC_FLAG_MAYBE |
968 DCERPC_PFC_FLAG_OBJECT_UUID);
969 if (!NT_STATUS_IS_OK(status)) {
970 return dcesrv_bind_nak(call,
971 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
974 /* max_recv_frag and max_xmit_frag result always in the same value! */
975 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
976 call->pkt.u.bind.max_recv_frag);
978 * The values are between 2048 and 5840 tested against Windows 2012R2
979 * via ncacn_ip_tcp on port 135.
981 max_req = MAX(2048, max_req);
982 max_rep = MIN(max_req, call->conn->max_recv_frag);
983 /* They are truncated to an 8 byte boundary. */
986 /* max_recv_frag and max_xmit_frag result always in the same value! */
987 call->conn->max_recv_frag = max_rep;
988 call->conn->max_xmit_frag = max_rep;
991 if provided, check the assoc_group is valid
993 if (call->pkt.u.bind.assoc_group_id != 0) {
994 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
996 call->pkt.u.bind.assoc_group_id);
998 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
999 call->conn->dce_ctx);
1003 * The NETLOGON server does not use handles and so
1004 * there is no need to support association groups, but
1005 * we need to give back a number regardless.
1007 * We have to do this when it is not run as a single process,
1008 * because then it can't see the other valid association
1009 * groups. We handle this genericly for all endpoints not
1010 * running in single process mode.
1012 * We know which endpoint we are on even before checking the
1013 * iface UUID, so for simplicity we enforce the same policy
1014 * for all interfaces on the endpoint.
1016 * This means that where NETLOGON
1017 * shares an endpoint (such as ncalrpc or of 'lsa over
1018 * netlogon' is set) we will still check association groups.
1022 if (call->conn->assoc_group == NULL &&
1023 !call->conn->endpoint->use_single_process) {
1024 call->conn->assoc_group
1025 = dcesrv_assoc_group_new(call->conn,
1026 call->conn->dce_ctx);
1028 if (call->conn->assoc_group == NULL) {
1029 return dcesrv_bind_nak(call, 0);
1032 if (call->pkt.u.bind.num_contexts < 1) {
1033 return dcesrv_bind_nak(call, 0);
1036 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1037 call->pkt.u.bind.num_contexts);
1038 if (ack_ctx_list == NULL) {
1039 return dcesrv_bind_nak(call, 0);
1043 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1044 * dcesrv_check_or_create_context()) and do some protocol validation
1045 * and set sane defaults.
1047 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1048 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1049 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1050 bool is_feature = false;
1051 uint64_t features = 0;
1053 if (c->num_transfer_syntaxes == 0) {
1054 return dcesrv_bind_nak(call, 0);
1057 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1058 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1061 * It's only treated as bind time feature request, if the first
1062 * transfer_syntax matches, all others are ignored.
1064 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1070 if (ack_features != NULL) {
1072 * Only one bind time feature context is allowed.
1074 return dcesrv_bind_nak(call, 0);
1078 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1079 a->reason.negotiate = 0;
1080 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1081 /* not supported yet */
1083 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1084 a->reason.negotiate |=
1085 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1088 call->conn->bind_time_features = a->reason.negotiate;
1092 * Try to negotiate one new presentation context.
1094 * Deep in here we locate the iface (by uuid) that the client
1095 * requested, from the list of interfaces on the
1096 * call->conn->endpoint, and call iface->bind() on that iface.
1098 * call->conn was set up at the accept() of the socket, and
1099 * call->conn->endpoint has a list of interfaces restricted to
1100 * this port or pipe.
1102 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1103 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1104 return dcesrv_bind_nak(call, 0);
1106 if (!NT_STATUS_IS_OK(status)) {
1111 * At this point we still don't know which interface (eg
1112 * netlogon, lsa, drsuapi) the caller requested in this bind!
1113 * The most recently added context is available as the first
1114 * element in the linked list at call->conn->contexts, that is
1115 * call->conn->contexts->iface, but they may not have
1116 * requested one at all!
1119 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1120 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1121 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1122 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1125 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1126 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1130 * After finding the interface and setting up the NDR
1131 * transport negotiation etc, handle any authentication that
1132 * is being requested.
1134 if (!dcesrv_auth_bind(call)) {
1136 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1138 * With DCERPC_AUTH_LEVEL_NONE, we get the
1139 * reject_reason in auth->auth_context_id.
1141 return dcesrv_bind_nak(call, auth->auth_context_id);
1145 * This must a be a temporary failure e.g. talloc or invalid
1146 * configuration, e.g. no machine account.
1148 return dcesrv_bind_nak(call,
1149 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1152 /* setup a bind_ack */
1153 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1154 pkt->auth_length = 0;
1155 pkt->call_id = call->pkt.call_id;
1156 pkt->ptype = DCERPC_PKT_BIND_ACK;
1157 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1158 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1159 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1160 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1162 endpoint = dcerpc_binding_get_string_option(
1163 call->conn->endpoint->ep_description,
1165 if (endpoint == NULL) {
1169 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1171 * TODO: check if this is really needed
1173 * Or if we should fix this in our idl files.
1175 ep_prefix = "\\PIPE\\";
1179 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1182 if (pkt->u.bind_ack.secondary_address == NULL) {
1183 return NT_STATUS_NO_MEMORY;
1185 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1186 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1187 pkt->u.bind_ack.auth_info = data_blob_null;
1189 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 return dcesrv_bind_nak(call, 0);
1194 if (auth->auth_finished) {
1195 return dcesrv_auth_reply(call);
1198 subreq = gensec_update_send(call, call->event_ctx,
1199 auth->gensec_security,
1200 call->in_auth_info.credentials);
1201 if (subreq == NULL) {
1202 return NT_STATUS_NO_MEMORY;
1204 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1206 return dcesrv_conn_auth_wait_setup(conn);
1209 static void dcesrv_bind_done(struct tevent_req *subreq)
1211 struct dcesrv_call_state *call =
1212 tevent_req_callback_data(subreq,
1213 struct dcesrv_call_state);
1214 struct dcesrv_connection *conn = call->conn;
1217 status = gensec_update_recv(subreq, call,
1218 &call->out_auth_info->credentials);
1219 TALLOC_FREE(subreq);
1221 status = dcesrv_auth_complete(call, status);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 status = dcesrv_bind_nak(call, 0);
1224 dcesrv_conn_auth_wait_finished(conn, status);
1228 status = dcesrv_auth_reply(call);
1229 dcesrv_conn_auth_wait_finished(conn, status);
1233 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1235 struct ncacn_packet *pkt = &call->ack_pkt;
1236 struct data_blob_list_item *rep = NULL;
1239 rep = talloc_zero(call, struct data_blob_list_item);
1241 return NT_STATUS_NO_MEMORY;
1244 status = ncacn_push_auth(&rep->blob, call, pkt,
1245 call->out_auth_info);
1246 if (!NT_STATUS_IS_OK(status)) {
1250 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1252 DLIST_ADD_END(call->replies, rep);
1253 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1255 if (call->conn->call_list && call->conn->call_list->replies) {
1256 if (call->conn->transport.report_output_data) {
1257 call->conn->transport.report_output_data(call->conn);
1261 return NT_STATUS_OK;
1265 static void dcesrv_auth3_done(struct tevent_req *subreq);
1268 handle a auth3 request
1270 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1272 struct dcesrv_connection *conn = call->conn;
1273 struct dcesrv_auth *auth = call->auth_state;
1274 struct tevent_req *subreq = NULL;
1277 if (!call->conn->allow_auth3) {
1278 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1281 if (auth->auth_finished) {
1282 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1285 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1287 call->pkt.u.auth3.auth_info.length,
1288 0, /* required flags */
1289 DCERPC_PFC_FLAG_FIRST |
1290 DCERPC_PFC_FLAG_LAST |
1291 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1292 0x08 | /* this is not defined, but should be ignored */
1293 DCERPC_PFC_FLAG_CONC_MPX |
1294 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1295 DCERPC_PFC_FLAG_MAYBE |
1296 DCERPC_PFC_FLAG_OBJECT_UUID);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1301 /* handle the auth3 in the auth code */
1302 if (!dcesrv_auth_prepare_auth3(call)) {
1304 * we don't send a reply to a auth3 request,
1305 * except by a fault.
1307 * In anycase we mark the connection as
1310 auth->auth_invalid = true;
1311 if (call->fault_code != 0) {
1312 return dcesrv_fault_disconnect(call, call->fault_code);
1315 return NT_STATUS_OK;
1318 subreq = gensec_update_send(call, call->event_ctx,
1319 auth->gensec_security,
1320 call->in_auth_info.credentials);
1321 if (subreq == NULL) {
1322 return NT_STATUS_NO_MEMORY;
1324 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1326 return dcesrv_conn_auth_wait_setup(conn);
1329 static void dcesrv_auth3_done(struct tevent_req *subreq)
1331 struct dcesrv_call_state *call =
1332 tevent_req_callback_data(subreq,
1333 struct dcesrv_call_state);
1334 struct dcesrv_connection *conn = call->conn;
1335 struct dcesrv_auth *auth = call->auth_state;
1338 status = gensec_update_recv(subreq, call,
1339 &call->out_auth_info->credentials);
1340 TALLOC_FREE(subreq);
1342 status = dcesrv_auth_complete(call, status);
1343 if (!NT_STATUS_IS_OK(status)) {
1345 * we don't send a reply to a auth3 request,
1346 * except by a fault.
1348 * In anycase we mark the connection as
1351 auth->auth_invalid = true;
1352 if (call->fault_code != 0) {
1353 status = dcesrv_fault_disconnect(call, call->fault_code);
1354 dcesrv_conn_auth_wait_finished(conn, status);
1358 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1363 * we don't send a reply to a auth3 request.
1366 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1371 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1372 const struct dcerpc_bind *b,
1373 const struct dcerpc_ctx_list *ctx,
1374 struct dcerpc_ack_ctx *ack,
1376 const struct ndr_syntax_id *supported_transfer)
1378 uint32_t if_version;
1379 struct dcesrv_connection_context *context;
1380 const struct dcesrv_interface *iface;
1383 const struct ndr_syntax_id *selected_transfer = NULL;
1388 return NT_STATUS_INTERNAL_ERROR;
1391 return NT_STATUS_INTERNAL_ERROR;
1393 if (ctx->num_transfer_syntaxes < 1) {
1394 return NT_STATUS_INTERNAL_ERROR;
1397 return NT_STATUS_INTERNAL_ERROR;
1399 if (supported_transfer == NULL) {
1400 return NT_STATUS_INTERNAL_ERROR;
1403 switch (ack->result) {
1404 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1405 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1407 * We is already completed.
1409 return NT_STATUS_OK;
1414 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1415 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1417 if_version = ctx->abstract_syntax.if_version;
1418 uuid = ctx->abstract_syntax.uuid;
1420 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1421 if (iface == NULL) {
1422 char *uuid_str = GUID_string(call, &uuid);
1423 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1424 talloc_free(uuid_str);
1426 * We report this only via ack->result
1428 return NT_STATUS_OK;
1431 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1432 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1434 if (validate_only) {
1436 * We report this only via ack->result
1438 return NT_STATUS_OK;
1441 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1443 * we only do NDR encoded dcerpc for now.
1445 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1446 supported_transfer);
1448 selected_transfer = supported_transfer;
1453 context = dcesrv_find_context(call->conn, ctx->context_id);
1454 if (context != NULL) {
1455 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1456 &ctx->abstract_syntax);
1458 return NT_STATUS_RPC_PROTOCOL_ERROR;
1461 if (selected_transfer != NULL) {
1462 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1465 return NT_STATUS_RPC_PROTOCOL_ERROR;
1468 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1469 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1470 ack->syntax = context->transfer_syntax;
1474 * We report this only via ack->result
1476 return NT_STATUS_OK;
1479 if (selected_transfer == NULL) {
1481 * We report this only via ack->result
1483 return NT_STATUS_OK;
1486 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1487 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1489 /* add this context to the list of available context_ids */
1490 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1491 if (context == NULL) {
1492 return NT_STATUS_NO_MEMORY;
1494 context->conn = call->conn;
1495 context->context_id = ctx->context_id;
1496 context->iface = iface;
1497 context->transfer_syntax = *selected_transfer;
1498 context->private_data = NULL;
1499 DLIST_ADD(call->conn->contexts, context);
1500 call->context = context;
1501 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1503 dcesrv_prepare_context_auth(call);
1506 * Multiplex is supported by default
1508 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1510 status = iface->bind(call, iface, if_version);
1511 call->context = NULL;
1512 if (!NT_STATUS_IS_OK(status)) {
1513 /* we don't want to trigger the iface->unbind() hook */
1514 context->iface = NULL;
1515 talloc_free(context);
1517 * We report this only via ack->result
1519 return NT_STATUS_OK;
1522 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1523 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1524 ack->syntax = context->transfer_syntax;
1525 return NT_STATUS_OK;
1528 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1529 const struct dcerpc_bind *b,
1530 struct dcerpc_ack_ctx *ack_ctx_list)
1534 bool validate_only = false;
1535 bool preferred_ndr32;
1538 * Try to negotiate one new presentation context,
1539 * using our preferred transfer syntax.
1541 for (i = 0; i < b->num_contexts; i++) {
1542 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1543 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1545 status = dcesrv_check_or_create_context(call, b, c, a,
1547 call->conn->preferred_transfer);
1548 if (!NT_STATUS_IS_OK(status)) {
1552 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1554 * We managed to negotiate one context.
1558 validate_only = true;
1562 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1563 call->conn->preferred_transfer);
1564 if (preferred_ndr32) {
1568 return NT_STATUS_OK;
1572 * Try to negotiate one new presentation context,
1573 * using NDR 32 as fallback.
1575 for (i = 0; i < b->num_contexts; i++) {
1576 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1577 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1579 status = dcesrv_check_or_create_context(call, b, c, a,
1581 &ndr_transfer_syntax_ndr);
1582 if (!NT_STATUS_IS_OK(status)) {
1586 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1588 * We managed to negotiate one context.
1592 validate_only = true;
1596 return NT_STATUS_OK;
1599 static void dcesrv_alter_done(struct tevent_req *subreq);
1602 handle a alter context request
1604 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1606 struct dcesrv_connection *conn = call->conn;
1608 bool auth_ok = false;
1609 struct ncacn_packet *pkt = &call->ack_pkt;
1610 uint32_t extra_flags = 0;
1611 struct dcesrv_auth *auth = call->auth_state;
1612 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1613 struct tevent_req *subreq = NULL;
1616 if (!call->conn->allow_alter) {
1617 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1620 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1622 call->pkt.u.alter.auth_info.length,
1623 0, /* required flags */
1624 DCERPC_PFC_FLAG_FIRST |
1625 DCERPC_PFC_FLAG_LAST |
1626 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1627 0x08 | /* this is not defined, but should be ignored */
1628 DCERPC_PFC_FLAG_CONC_MPX |
1629 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1630 DCERPC_PFC_FLAG_MAYBE |
1631 DCERPC_PFC_FLAG_OBJECT_UUID);
1632 if (!NT_STATUS_IS_OK(status)) {
1633 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1636 auth_ok = dcesrv_auth_alter(call);
1638 if (call->fault_code != 0) {
1639 return dcesrv_fault_disconnect(call, call->fault_code);
1643 if (call->pkt.u.alter.num_contexts < 1) {
1644 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1647 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1648 call->pkt.u.alter.num_contexts);
1649 if (ack_ctx_list == NULL) {
1650 return NT_STATUS_NO_MEMORY;
1654 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1655 * dcesrv_check_or_create_context()) and do some protocol validation
1656 * and set sane defaults.
1658 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1659 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1660 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1662 if (c->num_transfer_syntaxes == 0) {
1663 return dcesrv_fault_disconnect(call,
1664 DCERPC_NCA_S_PROTO_ERROR);
1667 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1668 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1672 * Try to negotiate one new presentation context.
1674 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1675 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1676 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1678 if (!NT_STATUS_IS_OK(status)) {
1682 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1683 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1684 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1685 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1688 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1689 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1692 /* handle any authentication that is being requested */
1694 if (call->in_auth_info.auth_type != auth->auth_type) {
1695 return dcesrv_fault_disconnect(call,
1696 DCERPC_FAULT_SEC_PKG_ERROR);
1698 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1701 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1702 pkt->auth_length = 0;
1703 pkt->call_id = call->pkt.call_id;
1704 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1705 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1706 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1707 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1708 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1709 pkt->u.alter_resp.secondary_address = "";
1710 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1711 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1712 pkt->u.alter_resp.auth_info = data_blob_null;
1714 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1719 if (auth->auth_finished) {
1720 return dcesrv_auth_reply(call);
1723 subreq = gensec_update_send(call, call->event_ctx,
1724 auth->gensec_security,
1725 call->in_auth_info.credentials);
1726 if (subreq == NULL) {
1727 return NT_STATUS_NO_MEMORY;
1729 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1731 return dcesrv_conn_auth_wait_setup(conn);
1734 static void dcesrv_alter_done(struct tevent_req *subreq)
1736 struct dcesrv_call_state *call =
1737 tevent_req_callback_data(subreq,
1738 struct dcesrv_call_state);
1739 struct dcesrv_connection *conn = call->conn;
1742 status = gensec_update_recv(subreq, call,
1743 &call->out_auth_info->credentials);
1744 TALLOC_FREE(subreq);
1746 status = dcesrv_auth_complete(call, status);
1747 if (!NT_STATUS_IS_OK(status)) {
1748 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1749 dcesrv_conn_auth_wait_finished(conn, status);
1753 status = dcesrv_auth_reply(call);
1754 dcesrv_conn_auth_wait_finished(conn, status);
1759 possibly save the call for inspection with ndrdump
1761 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1765 const char *dump_dir;
1766 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1770 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1772 call->context->iface->name,
1773 call->pkt.u.request.opnum,
1775 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1776 DEBUG(0,("RPC SAVED %s\n", fname));
1782 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1784 TALLOC_CTX *frame = talloc_stackframe();
1785 const struct dcesrv_auth *auth = call->auth_state;
1786 const uint32_t bitmask1 = auth->client_hdr_signing ?
1787 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1788 const struct dcerpc_sec_vt_pcontext pcontext = {
1789 .abstract_syntax = call->context->iface->syntax_id,
1790 .transfer_syntax = call->context->transfer_syntax,
1792 const struct dcerpc_sec_vt_header2 header2 =
1793 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1794 enum ndr_err_code ndr_err;
1795 struct dcerpc_sec_verification_trailer *vt = NULL;
1796 NTSTATUS status = NT_STATUS_OK;
1799 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1801 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1803 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1804 status = ndr_map_error2ntstatus(ndr_err);
1808 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1809 &pcontext, &header2);
1811 status = NT_STATUS_ACCESS_DENIED;
1820 handle a dcerpc request packet
1822 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1824 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1825 struct dcesrv_auth *auth = call->auth_state;
1826 enum dcerpc_transport_t transport =
1827 dcerpc_binding_get_transport(endpoint->ep_description);
1828 struct ndr_pull *pull;
1831 if (!call->conn->allow_request) {
1832 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1835 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1836 if (auth->gensec_security != NULL &&
1837 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1838 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1841 if (call->context == NULL) {
1842 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1843 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1846 switch (auth->auth_level) {
1847 case DCERPC_AUTH_LEVEL_NONE:
1848 case DCERPC_AUTH_LEVEL_PACKET:
1849 case DCERPC_AUTH_LEVEL_INTEGRITY:
1850 case DCERPC_AUTH_LEVEL_PRIVACY:
1853 if (!call->context->allow_connect) {
1856 addr = tsocket_address_string(call->conn->remote_address,
1859 DEBUG(2, ("%s: restrict auth_level_connect access "
1860 "to [%s] with auth[type=0x%x,level=0x%x] "
1861 "on [%s] from [%s]\n",
1862 __func__, call->context->iface->name,
1865 derpc_transport_string_by_transport(transport),
1867 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1872 if (auth->auth_level < call->context->min_auth_level) {
1875 addr = tsocket_address_string(call->conn->remote_address, call);
1877 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1878 "to [%s] with auth[type=0x%x,level=0x%x] "
1879 "on [%s] from [%s]\n",
1881 call->context->min_auth_level,
1882 call->context->iface->name,
1885 derpc_transport_string_by_transport(transport),
1887 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1890 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1891 NT_STATUS_HAVE_NO_MEMORY(pull);
1893 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1895 call->ndr_pull = pull;
1897 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1898 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1901 status = dcesrv_check_verification_trailer(call);
1902 if (!NT_STATUS_IS_OK(status)) {
1903 uint32_t faultcode = DCERPC_FAULT_OTHER;
1904 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1905 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1907 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1908 nt_errstr(status)));
1909 return dcesrv_fault(call, faultcode);
1912 /* unravel the NDR for the packet */
1913 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1914 if (!NT_STATUS_IS_OK(status)) {
1915 uint8_t extra_flags = 0;
1916 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1917 /* we got an unknown call */
1918 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1919 call->pkt.u.request.opnum,
1920 call->context->iface->name));
1921 dcesrv_save_call(call, "unknown");
1922 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1924 dcesrv_save_call(call, "pullfail");
1926 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1929 if (pull->offset != pull->data_size) {
1930 dcesrv_save_call(call, "extrabytes");
1931 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1932 pull->data_size - pull->offset));
1935 /* call the dispatch function */
1936 status = call->context->iface->dispatch(call, call, call->r);
1937 if (!NT_STATUS_IS_OK(status)) {
1938 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1939 call->context->iface->name,
1940 call->pkt.u.request.opnum,
1941 dcerpc_errstr(pull, call->fault_code)));
1942 return dcesrv_fault(call, call->fault_code);
1945 /* add the call to the pending list */
1946 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1948 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1949 return NT_STATUS_OK;
1952 return dcesrv_reply(call);
1957 remove the call from the right list when freed
1959 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1961 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1965 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1967 return conn->local_address;
1970 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1972 return conn->remote_address;
1976 process some input to a dcerpc endpoint server.
1978 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1979 struct ncacn_packet *pkt,
1983 struct dcesrv_call_state *call;
1984 struct dcesrv_call_state *existing = NULL;
1986 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1988 data_blob_free(&blob);
1990 return NT_STATUS_NO_MEMORY;
1992 call->conn = dce_conn;
1993 call->event_ctx = dce_conn->event_ctx;
1994 call->msg_ctx = dce_conn->msg_ctx;
1995 call->state_flags = call->conn->state_flags;
1996 call->time = timeval_current();
1997 call->list = DCESRV_LIST_NONE;
1999 talloc_steal(call, pkt);
2000 talloc_steal(call, blob.data);
2003 call->auth_state = &dce_conn->auth_state;
2005 talloc_set_destructor(call, dcesrv_call_dequeue);
2007 if (call->conn->allow_bind) {
2009 * Only one bind is possible per connection
2011 call->conn->allow_bind = false;
2012 return dcesrv_bind(call);
2015 /* we have to check the signing here, before combining the
2017 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2018 if (!call->conn->allow_request) {
2019 return dcesrv_fault_disconnect(call,
2020 DCERPC_NCA_S_PROTO_ERROR);
2023 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2025 call->pkt.u.request.stub_and_verifier.length,
2026 0, /* required_flags */
2027 DCERPC_PFC_FLAG_FIRST |
2028 DCERPC_PFC_FLAG_LAST |
2029 DCERPC_PFC_FLAG_PENDING_CANCEL |
2030 0x08 | /* this is not defined, but should be ignored */
2031 DCERPC_PFC_FLAG_CONC_MPX |
2032 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2033 DCERPC_PFC_FLAG_MAYBE |
2034 DCERPC_PFC_FLAG_OBJECT_UUID);
2035 if (!NT_STATUS_IS_OK(status)) {
2036 return dcesrv_fault_disconnect(call,
2037 DCERPC_NCA_S_PROTO_ERROR);
2040 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2042 * We don't use dcesrv_fault_disconnect()
2043 * here, because we don't want to set
2044 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2046 * Note that we don't check against the negotiated
2047 * max_recv_frag, but a hard coded value.
2049 dcesrv_call_disconnect_after(call,
2050 "dcesrv_auth_request - frag_length too large");
2051 return dcesrv_fault(call,
2052 DCERPC_NCA_S_PROTO_ERROR);
2055 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2056 if (dce_conn->pending_call_list != NULL) {
2058 * concurrent requests are only allowed
2059 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2061 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2062 dcesrv_call_disconnect_after(call,
2063 "dcesrv_auth_request - "
2064 "existing pending call without CONN_MPX");
2065 return dcesrv_fault(call,
2066 DCERPC_NCA_S_PROTO_ERROR);
2069 /* only one request is possible in the fragmented list */
2070 if (dce_conn->incoming_fragmented_call_list != NULL) {
2071 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2073 * Without DCERPC_PFC_FLAG_CONC_MPX
2074 * we need to return the FAULT on the
2075 * already existing call.
2077 * This is important to get the
2078 * call_id and context_id right.
2081 call = dce_conn->incoming_fragmented_call_list;
2083 dcesrv_call_disconnect_after(call,
2084 "dcesrv_auth_request - "
2085 "existing fragmented call");
2086 return dcesrv_fault(call,
2087 DCERPC_NCA_S_PROTO_ERROR);
2089 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2090 return dcesrv_fault_disconnect(call,
2091 DCERPC_FAULT_NO_CALL_ACTIVE);
2093 call->context = dcesrv_find_context(call->conn,
2094 call->pkt.u.request.context_id);
2095 if (call->context == NULL) {
2096 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2097 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2100 const struct dcerpc_request *nr = &call->pkt.u.request;
2101 const struct dcerpc_request *er = NULL;
2104 existing = dcesrv_find_fragmented_call(dce_conn,
2106 if (existing == NULL) {
2107 dcesrv_call_disconnect_after(call,
2108 "dcesrv_auth_request - "
2109 "no existing fragmented call");
2110 return dcesrv_fault(call,
2111 DCERPC_NCA_S_PROTO_ERROR);
2113 er = &existing->pkt.u.request;
2115 if (call->pkt.ptype != existing->pkt.ptype) {
2116 /* trying to play silly buggers are we? */
2117 return dcesrv_fault_disconnect(existing,
2118 DCERPC_NCA_S_PROTO_ERROR);
2120 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2123 return dcesrv_fault_disconnect(existing,
2124 DCERPC_NCA_S_PROTO_ERROR);
2126 if (nr->context_id != er->context_id) {
2127 return dcesrv_fault_disconnect(existing,
2128 DCERPC_NCA_S_PROTO_ERROR);
2130 if (nr->opnum != er->opnum) {
2131 return dcesrv_fault_disconnect(existing,
2132 DCERPC_NCA_S_PROTO_ERROR);
2137 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2139 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2141 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2142 payload_offset += 16;
2145 ok = dcesrv_auth_pkt_pull(call, &blob,
2146 0, /* required_flags */
2147 DCERPC_PFC_FLAG_FIRST |
2148 DCERPC_PFC_FLAG_LAST |
2149 DCERPC_PFC_FLAG_PENDING_CANCEL |
2150 0x08 | /* this is not defined, but should be ignored */
2151 DCERPC_PFC_FLAG_CONC_MPX |
2152 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2153 DCERPC_PFC_FLAG_MAYBE |
2154 DCERPC_PFC_FLAG_OBJECT_UUID,
2156 &call->pkt.u.request.stub_and_verifier);
2159 * We don't use dcesrv_fault_disconnect()
2160 * here, because we don't want to set
2161 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2163 dcesrv_call_disconnect_after(call,
2164 "dcesrv_auth_request - failed");
2165 if (call->fault_code == 0) {
2166 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2168 return dcesrv_fault(call, call->fault_code);
2172 /* see if this is a continued packet */
2173 if (existing != NULL) {
2174 struct dcerpc_request *er = &existing->pkt.u.request;
2175 const struct dcerpc_request *nr = &call->pkt.u.request;
2181 * Up to 4 MByte are allowed by all fragments
2183 available = dce_conn->max_total_request_size;
2184 if (er->stub_and_verifier.length > available) {
2185 dcesrv_call_disconnect_after(existing,
2186 "dcesrv_auth_request - existing payload too large");
2187 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2189 available -= er->stub_and_verifier.length;
2190 if (nr->alloc_hint > available) {
2191 dcesrv_call_disconnect_after(existing,
2192 "dcesrv_auth_request - alloc hint too large");
2193 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2195 if (nr->stub_and_verifier.length > available) {
2196 dcesrv_call_disconnect_after(existing,
2197 "dcesrv_auth_request - new payload too large");
2198 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2200 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2201 /* allocate at least 1 byte */
2202 alloc_hint = MAX(alloc_hint, 1);
2203 alloc_size = er->stub_and_verifier.length +
2204 nr->stub_and_verifier.length;
2205 alloc_size = MAX(alloc_size, alloc_hint);
2207 er->stub_and_verifier.data =
2208 talloc_realloc(existing,
2209 er->stub_and_verifier.data,
2210 uint8_t, alloc_size);
2211 if (er->stub_and_verifier.data == NULL) {
2213 return dcesrv_fault_with_flags(existing,
2214 DCERPC_FAULT_OUT_OF_RESOURCES,
2215 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2217 memcpy(er->stub_and_verifier.data +
2218 er->stub_and_verifier.length,
2219 nr->stub_and_verifier.data,
2220 nr->stub_and_verifier.length);
2221 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2223 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2229 /* this may not be the last pdu in the chain - if its isn't then
2230 just put it on the incoming_fragmented_call_list and wait for the rest */
2231 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2232 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2234 * Up to 4 MByte are allowed by all fragments
2236 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2237 dcesrv_call_disconnect_after(call,
2238 "dcesrv_auth_request - initial alloc hint too large");
2239 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2241 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2242 return NT_STATUS_OK;
2245 /* This removes any fragments we may have had stashed away */
2246 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2248 switch (call->pkt.ptype) {
2249 case DCERPC_PKT_BIND:
2250 status = dcesrv_bind_nak(call,
2251 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2253 case DCERPC_PKT_AUTH3:
2254 status = dcesrv_auth3(call);
2256 case DCERPC_PKT_ALTER:
2257 status = dcesrv_alter(call);
2259 case DCERPC_PKT_REQUEST:
2260 status = dcesrv_request(call);
2262 case DCERPC_PKT_CO_CANCEL:
2263 case DCERPC_PKT_ORPHANED:
2265 * Window just ignores CO_CANCEL and ORPHANED,
2268 status = NT_STATUS_OK;
2271 case DCERPC_PKT_BIND_ACK:
2272 case DCERPC_PKT_BIND_NAK:
2273 case DCERPC_PKT_ALTER_RESP:
2274 case DCERPC_PKT_RESPONSE:
2275 case DCERPC_PKT_FAULT:
2276 case DCERPC_PKT_SHUTDOWN:
2278 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2282 /* if we are going to be sending a reply then add
2283 it to the list of pending calls. We add it to the end to keep the call
2284 list in the order we will answer */
2285 if (!NT_STATUS_IS_OK(status)) {
2292 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2293 struct loadparm_context *lp_ctx,
2294 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2297 struct dcesrv_context *dce_ctx;
2300 if (!endpoint_servers) {
2301 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2302 return NT_STATUS_INTERNAL_ERROR;
2305 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2306 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2308 if (uid_wrapper_enabled()) {
2309 setenv("UID_WRAPPER_MYUID", "1", 1);
2311 dce_ctx->initial_euid = geteuid();
2312 if (uid_wrapper_enabled()) {
2313 unsetenv("UID_WRAPPER_MYUID");
2316 dce_ctx->endpoint_list = NULL;
2317 dce_ctx->lp_ctx = lp_ctx;
2318 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2319 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2320 dce_ctx->broken_connections = NULL;
2322 for (i=0;endpoint_servers[i];i++) {
2323 const struct dcesrv_endpoint_server *ep_server;
2325 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2327 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2328 return NT_STATUS_INTERNAL_ERROR;
2331 status = ep_server->init_server(dce_ctx, ep_server);
2332 if (!NT_STATUS_IS_OK(status)) {
2333 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2334 nt_errstr(status)));
2339 *_dce_ctx = dce_ctx;
2340 return NT_STATUS_OK;
2343 /* the list of currently registered DCERPC endpoint servers.
2345 static struct ep_server {
2346 struct dcesrv_endpoint_server *ep_server;
2347 } *ep_servers = NULL;
2348 static int num_ep_servers;
2351 register a DCERPC endpoint server.
2353 The 'name' can be later used by other backends to find the operations
2354 structure for this backend.
2357 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2360 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2361 /* its already registered! */
2362 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2364 return NT_STATUS_OBJECT_NAME_COLLISION;
2367 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2369 smb_panic("out of memory in dcerpc_register");
2372 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2373 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2377 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2380 return NT_STATUS_OK;
2384 return the operations structure for a named backend of the specified type
2386 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2390 for (i=0;i<num_ep_servers;i++) {
2391 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2392 return ep_servers[i].ep_server;
2399 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2401 static bool initialized;
2402 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2403 STATIC_dcerpc_server_MODULES_PROTO;
2404 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2405 init_module_fn *shared_init;
2412 shared_init = load_samba_modules(NULL, "dcerpc_server");
2414 run_init_functions(NULL, static_init);
2415 run_init_functions(NULL, shared_init);
2417 talloc_free(shared_init);
2421 return the DCERPC module version, and the size of some critical types
2422 This can be used by endpoint server modules to either detect compilation errors, or provide
2423 multiple implementations for different smbd compilation options in one module
2425 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2427 static const struct dcesrv_critical_sizes critical_sizes = {
2428 DCERPC_MODULE_VERSION,
2429 sizeof(struct dcesrv_context),
2430 sizeof(struct dcesrv_endpoint),
2431 sizeof(struct dcesrv_endpoint_server),
2432 sizeof(struct dcesrv_interface),
2433 sizeof(struct dcesrv_if_list),
2434 sizeof(struct dcesrv_connection),
2435 sizeof(struct dcesrv_call_state),
2436 sizeof(struct dcesrv_auth),
2437 sizeof(struct dcesrv_handle)
2440 return &critical_sizes;
2443 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2445 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2446 struct stream_connection *srv_conn;
2447 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2448 struct stream_connection);
2450 dce_conn->wait_send = NULL;
2451 dce_conn->wait_recv = NULL;
2452 dce_conn->wait_private = NULL;
2454 dce_conn->allow_bind = false;
2455 dce_conn->allow_auth3 = false;
2456 dce_conn->allow_alter = false;
2457 dce_conn->allow_request = false;
2459 if (dce_conn->pending_call_list == NULL) {
2460 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2462 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2463 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2467 if (dce_conn->terminate != NULL) {
2471 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2473 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2474 if (dce_conn->terminate == NULL) {
2475 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2477 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2480 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2482 struct dcesrv_connection *cur, *next;
2484 next = dce_ctx->broken_connections;
2485 while (next != NULL) {
2489 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2490 struct dcesrv_connection_context *context_cur, *context_next;
2492 context_next = cur->contexts;
2493 while (context_next != NULL) {
2494 context_cur = context_next;
2495 context_next = context_cur->next;
2497 dcesrv_connection_context_destructor(context_cur);
2501 dcesrv_terminate_connection(cur, cur->terminate);
2505 /* We need this include to be able to compile on some plateforms
2506 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2508 * It has to be that deep because otherwise we have a conflict on
2509 * const struct dcesrv_interface declaration.
2510 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2511 * which conflict with the bind used before.
2513 #include "system/network.h"
2515 struct dcesrv_sock_reply_state {
2516 struct dcesrv_connection *dce_conn;
2517 struct dcesrv_call_state *call;
2521 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2522 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2524 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2526 struct dcesrv_call_state *call;
2528 call = dce_conn->call_list;
2529 if (!call || !call->replies) {
2533 while (call->replies) {
2534 struct data_blob_list_item *rep = call->replies;
2535 struct dcesrv_sock_reply_state *substate;
2536 struct tevent_req *subreq;
2538 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2540 dcesrv_terminate_connection(dce_conn, "no memory");
2544 substate->dce_conn = dce_conn;
2545 substate->call = NULL;
2547 DLIST_REMOVE(call->replies, rep);
2549 if (call->replies == NULL && call->terminate_reason == NULL) {
2550 substate->call = call;
2553 substate->iov.iov_base = (void *) rep->blob.data;
2554 substate->iov.iov_len = rep->blob.length;
2556 subreq = tstream_writev_queue_send(substate,
2557 dce_conn->event_ctx,
2559 dce_conn->send_queue,
2562 dcesrv_terminate_connection(dce_conn, "no memory");
2565 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2569 if (call->terminate_reason != NULL) {
2570 struct tevent_req *subreq;
2572 subreq = tevent_queue_wait_send(call,
2573 dce_conn->event_ctx,
2574 dce_conn->send_queue);
2576 dcesrv_terminate_connection(dce_conn, __location__);
2579 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2583 DLIST_REMOVE(call->conn->call_list, call);
2584 call->list = DCESRV_LIST_NONE;
2587 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2589 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2590 struct dcesrv_sock_reply_state);
2594 struct dcesrv_call_state *call = substate->call;
2596 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2597 TALLOC_FREE(subreq);
2599 status = map_nt_error_from_unix_common(sys_errno);
2600 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2604 talloc_free(substate);
2610 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2612 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2614 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2615 struct dcesrv_call_state);
2619 /* make sure we stop send queue before removing subreq */
2620 tevent_queue_stop(call->conn->send_queue);
2622 ok = tevent_queue_wait_recv(subreq);
2623 TALLOC_FREE(subreq);
2625 dcesrv_terminate_connection(call->conn, __location__);
2629 /* disconnect after 200 usecs */
2630 tv = timeval_current_ofs_usec(200);
2631 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2632 if (subreq == NULL) {
2633 dcesrv_terminate_connection(call->conn, __location__);
2636 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2640 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2642 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2643 struct dcesrv_call_state);
2646 ok = tevent_wakeup_recv(subreq);
2647 TALLOC_FREE(subreq);
2649 dcesrv_terminate_connection(call->conn, __location__);
2653 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2656 struct dcesrv_socket_context {
2657 const struct dcesrv_endpoint *endpoint;
2658 struct dcesrv_context *dcesrv_ctx;
2662 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2664 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2667 struct dcesrv_socket_context *dcesrv_sock =
2668 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2669 enum dcerpc_transport_t transport =
2670 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2671 struct dcesrv_connection *dcesrv_conn = NULL;
2673 struct tevent_req *subreq;
2674 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2676 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2678 if (!srv_conn->session_info) {
2679 status = auth_anonymous_session_info(srv_conn,
2681 &srv_conn->session_info);
2682 if (!NT_STATUS_IS_OK(status)) {
2683 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2684 nt_errstr(status)));
2685 stream_terminate_connection(srv_conn, nt_errstr(status));
2691 * This fills in dcesrv_conn->endpoint with the endpoint
2692 * associated with the socket. From this point on we know
2693 * which (group of) services we are handling, but not the
2694 * specific interface.
2697 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2699 dcesrv_sock->endpoint,
2700 srv_conn->session_info,
2701 srv_conn->event.ctx,
2703 srv_conn->server_id,
2704 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2706 if (!NT_STATUS_IS_OK(status)) {
2707 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2708 nt_errstr(status)));
2709 stream_terminate_connection(srv_conn, nt_errstr(status));
2713 dcesrv_conn->transport.private_data = srv_conn;
2714 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2716 TALLOC_FREE(srv_conn->event.fde);
2718 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2719 if (!dcesrv_conn->send_queue) {
2720 status = NT_STATUS_NO_MEMORY;
2721 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2722 nt_errstr(status)));
2723 stream_terminate_connection(srv_conn, nt_errstr(status));
2727 if (transport == NCACN_NP) {
2728 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2729 &srv_conn->tstream);
2731 ret = tstream_bsd_existing_socket(dcesrv_conn,
2732 socket_get_fd(srv_conn->socket),
2733 &dcesrv_conn->stream);
2735 status = map_nt_error_from_unix_common(errno);
2736 DEBUG(0, ("dcesrv_sock_accept: "
2737 "failed to setup tstream: %s\n",
2738 nt_errstr(status)));
2739 stream_terminate_connection(srv_conn, nt_errstr(status));
2742 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2745 dcesrv_conn->local_address = srv_conn->local_address;
2746 dcesrv_conn->remote_address = srv_conn->remote_address;
2748 if (transport == NCALRPC) {
2753 sock_fd = socket_get_fd(srv_conn->socket);
2754 if (sock_fd == -1) {
2755 stream_terminate_connection(
2756 srv_conn, "socket_get_fd failed\n");
2760 ret = getpeereid(sock_fd, &uid, &gid);
2762 status = map_nt_error_from_unix_common(errno);
2763 DEBUG(0, ("dcesrv_sock_accept: "
2764 "getpeereid() failed for NCALRPC: %s\n",
2765 nt_errstr(status)));
2766 stream_terminate_connection(srv_conn, nt_errstr(status));
2769 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2770 struct tsocket_address *r = NULL;
2772 ret = tsocket_address_unix_from_path(dcesrv_conn,
2773 AS_SYSTEM_MAGIC_PATH_TOKEN,
2776 status = map_nt_error_from_unix_common(errno);
2777 DEBUG(0, ("dcesrv_sock_accept: "
2778 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2779 nt_errstr(status)));
2780 stream_terminate_connection(srv_conn, nt_errstr(status));
2783 dcesrv_conn->remote_address = r;
2787 srv_conn->private_data = dcesrv_conn;
2789 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2790 dcesrv_conn->event_ctx,
2791 dcesrv_conn->stream);
2793 status = NT_STATUS_NO_MEMORY;
2794 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2795 nt_errstr(status)));
2796 stream_terminate_connection(srv_conn, nt_errstr(status));
2799 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2804 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2806 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2808 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2809 struct dcesrv_connection);
2810 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2811 struct ncacn_packet *pkt;
2815 if (dce_conn->terminate) {
2817 * if the current connection is broken
2818 * we need to clean it up before any other connection
2820 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2821 dcesrv_cleanup_broken_connections(dce_ctx);
2825 dcesrv_cleanup_broken_connections(dce_ctx);
2827 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2829 TALLOC_FREE(subreq);
2830 if (!NT_STATUS_IS_OK(status)) {
2831 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2835 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2836 if (!NT_STATUS_IS_OK(status)) {
2837 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2842 * This is used to block the connection during
2843 * pending authentication.
2845 if (dce_conn->wait_send != NULL) {
2846 subreq = dce_conn->wait_send(dce_conn,
2847 dce_conn->event_ctx,
2848 dce_conn->wait_private);
2850 status = NT_STATUS_NO_MEMORY;
2851 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2854 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2858 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2859 dce_conn->event_ctx,
2862 status = NT_STATUS_NO_MEMORY;
2863 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2866 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2869 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2871 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2872 struct dcesrv_connection);
2873 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2876 if (dce_conn->terminate) {
2878 * if the current connection is broken
2879 * we need to clean it up before any other connection
2881 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2882 dcesrv_cleanup_broken_connections(dce_ctx);
2886 dcesrv_cleanup_broken_connections(dce_ctx);
2888 status = dce_conn->wait_recv(subreq);
2889 dce_conn->wait_send = NULL;
2890 dce_conn->wait_recv = NULL;
2891 dce_conn->wait_private = NULL;
2892 TALLOC_FREE(subreq);
2893 if (!NT_STATUS_IS_OK(status)) {
2894 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2898 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2899 dce_conn->event_ctx,
2902 status = NT_STATUS_NO_MEMORY;
2903 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2906 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2909 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2911 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2912 struct dcesrv_connection);
2913 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2916 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2918 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2919 struct dcesrv_connection);
2920 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2924 static const struct stream_server_ops dcesrv_stream_ops = {
2926 .accept_connection = dcesrv_sock_accept,
2927 .recv_handler = dcesrv_sock_recv,
2928 .send_handler = dcesrv_sock_send,
2931 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2932 struct loadparm_context *lp_ctx,
2933 struct dcesrv_endpoint *e,
2934 struct tevent_context *event_ctx,
2935 const struct model_ops *model_ops,
2936 void *process_context)
2938 struct dcesrv_socket_context *dcesrv_sock;
2941 const char *endpoint;
2943 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2944 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2946 /* remember the endpoint of this socket */
2947 dcesrv_sock->endpoint = e;
2948 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2950 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2952 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2953 model_ops, &dcesrv_stream_ops,
2954 "unix", endpoint, &port,
2955 lpcfg_socket_options(lp_ctx),
2956 dcesrv_sock, process_context);
2957 if (!NT_STATUS_IS_OK(status)) {
2958 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2959 endpoint, nt_errstr(status)));
2965 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2966 struct loadparm_context *lp_ctx,
2967 struct dcesrv_endpoint *e,
2968 struct tevent_context *event_ctx,
2969 const struct model_ops *model_ops,
2970 void *process_context)
2972 struct dcesrv_socket_context *dcesrv_sock;
2976 const char *endpoint;
2978 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2980 if (endpoint == NULL) {
2982 * No identifier specified: use DEFAULT.
2984 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2985 * no endpoint and let the epmapper worry about it.
2987 endpoint = "DEFAULT";
2988 status = dcerpc_binding_set_string_option(e->ep_description,
2991 if (!NT_STATUS_IS_OK(status)) {
2992 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2993 nt_errstr(status)));
2998 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
3001 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3002 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3004 /* remember the endpoint of this socket */
3005 dcesrv_sock->endpoint = e;
3006 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3008 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3009 model_ops, &dcesrv_stream_ops,
3010 "unix", full_path, &port,
3011 lpcfg_socket_options(lp_ctx),
3012 dcesrv_sock, process_context);
3013 if (!NT_STATUS_IS_OK(status)) {
3014 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3015 endpoint, full_path, nt_errstr(status)));
3020 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3021 struct loadparm_context *lp_ctx,
3022 struct dcesrv_endpoint *e,
3023 struct tevent_context *event_ctx,
3024 const struct model_ops *model_ops,
3025 void *process_context)
3027 struct dcesrv_socket_context *dcesrv_sock;
3029 const char *endpoint;
3031 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3032 if (endpoint == NULL) {
3033 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3034 return NT_STATUS_INVALID_PARAMETER;
3037 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3038 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3040 /* remember the endpoint of this socket */
3041 dcesrv_sock->endpoint = e;
3042 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3044 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3045 model_ops, &dcesrv_stream_ops,
3047 dcesrv_sock, process_context);
3048 if (!NT_STATUS_IS_OK(status)) {
3049 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3050 endpoint, nt_errstr(status)));
3054 return NT_STATUS_OK;
3058 add a socket address to the list of events, one event per dcerpc endpoint
3060 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3061 struct dcesrv_endpoint *e,
3062 struct tevent_context *event_ctx,
3063 const struct model_ops *model_ops,
3064 const char *address,
3065 void *process_context)
3067 struct dcesrv_socket_context *dcesrv_sock;
3070 const char *endpoint;
3073 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3074 if (endpoint != NULL) {
3075 port = atoi(endpoint);
3078 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3079 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3081 /* remember the endpoint of this socket */
3082 dcesrv_sock->endpoint = e;
3083 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3085 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3086 model_ops, &dcesrv_stream_ops,
3087 "ip", address, &port,
3088 lpcfg_socket_options(dce_ctx->lp_ctx),
3089 dcesrv_sock, process_context);
3090 if (!NT_STATUS_IS_OK(status)) {
3091 struct dcesrv_if_list *iface;
3092 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3094 for (iface = e->interface_list; iface; iface = iface->next) {
3095 DEBUGADD(0, ("%s ", iface->iface.name));
3097 DEBUGADD(0, ("failed - %s",
3098 nt_errstr(status)));
3102 snprintf(port_str, sizeof(port_str), "%u", port);
3104 status = dcerpc_binding_set_string_option(e->ep_description,
3105 "endpoint", port_str);
3106 if (!NT_STATUS_IS_OK(status)) {
3107 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3108 port_str, nt_errstr(status)));
3111 struct dcesrv_if_list *iface;
3112 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3113 address, port_str));
3114 for (iface = e->interface_list; iface; iface = iface->next) {
3115 DEBUGADD(4, ("%s ", iface->iface.name));
3117 DEBUGADD(4, ("\n"));
3120 return NT_STATUS_OK;
3123 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3125 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3126 struct loadparm_context *lp_ctx,
3127 struct dcesrv_endpoint *e,
3128 struct tevent_context *event_ctx,
3129 const struct model_ops *model_ops,
3130 void *process_context)
3134 /* Add TCP/IP sockets */
3135 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3138 struct interface *ifaces;
3140 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3142 num_interfaces = iface_list_count(ifaces);
3143 for(i = 0; i < num_interfaces; i++) {
3144 const char *address = iface_list_n_ip(ifaces, i);
3145 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3148 NT_STATUS_NOT_OK_RETURN(status);
3153 size_t num_binds = 0;
3154 wcard = iface_list_wildcard(dce_ctx);
3155 NT_STATUS_HAVE_NO_MEMORY(wcard);
3156 for (i=0; wcard[i]; i++) {
3157 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3158 model_ops, wcard[i],
3160 if (NT_STATUS_IS_OK(status)) {
3165 if (num_binds == 0) {
3166 return NT_STATUS_INVALID_PARAMETER_MIX;
3170 return NT_STATUS_OK;
3173 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3174 struct loadparm_context *lp_ctx,
3175 struct dcesrv_endpoint *e,
3176 struct tevent_context *event_ctx,
3177 const struct model_ops *model_ops,
3178 void *process_context)
3180 enum dcerpc_transport_t transport =
3181 dcerpc_binding_get_transport(e->ep_description);
3183 switch (transport) {
3184 case NCACN_UNIX_STREAM:
3185 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3186 model_ops, process_context);
3189 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3190 model_ops, process_context);
3193 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3194 model_ops, process_context);
3197 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3198 model_ops, process_context);
3201 return NT_STATUS_NOT_SUPPORTED;
3207 * retrieve credentials from a dce_call
3209 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3211 struct dcesrv_auth *auth = dce_call->auth_state;
3212 return auth->session_info->credentials;
3216 * returns true if this is an authenticated call
3218 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3220 struct dcesrv_auth *auth = dce_call->auth_state;
3221 enum security_user_level level;
3222 level = security_session_user_level(auth->session_info, NULL);
3223 return level >= SECURITY_USER;
3227 * retrieve account_name for a dce_call
3229 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3231 struct dcesrv_auth *auth = dce_call->auth_state;
3232 return auth->session_info->info->account_name;
3236 * retrieve session_info from a dce_call
3238 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3240 struct dcesrv_auth *auth = dce_call->auth_state;
3241 return auth->session_info;
3245 * retrieve auth type/level from a dce_call
3247 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3248 enum dcerpc_AuthType *auth_type,
3249 enum dcerpc_AuthLevel *auth_level)
3251 struct dcesrv_auth *auth = dce_call->auth_state;
3253 if (auth_type != NULL) {
3254 *auth_type = auth->auth_type;
3256 if (auth_level != NULL) {
3257 *auth_level = auth->auth_level;