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->conn->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->conn->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->conn->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->conn->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 (call->conn->auth_state.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 call->conn->auth_state.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;
1337 status = gensec_update_recv(subreq, call,
1338 &call->out_auth_info->credentials);
1339 TALLOC_FREE(subreq);
1341 status = dcesrv_auth_complete(call, status);
1342 if (!NT_STATUS_IS_OK(status)) {
1344 * we don't send a reply to a auth3 request,
1345 * except by a fault.
1347 * In anycase we mark the connection as
1350 call->conn->auth_state.auth_invalid = true;
1351 if (call->fault_code != 0) {
1352 status = dcesrv_fault_disconnect(call, call->fault_code);
1353 dcesrv_conn_auth_wait_finished(conn, status);
1357 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1362 * we don't send a reply to a auth3 request.
1365 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1370 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1371 const struct dcerpc_bind *b,
1372 const struct dcerpc_ctx_list *ctx,
1373 struct dcerpc_ack_ctx *ack,
1375 const struct ndr_syntax_id *supported_transfer)
1377 uint32_t if_version;
1378 struct dcesrv_connection_context *context;
1379 const struct dcesrv_interface *iface;
1382 const struct ndr_syntax_id *selected_transfer = NULL;
1387 return NT_STATUS_INTERNAL_ERROR;
1390 return NT_STATUS_INTERNAL_ERROR;
1392 if (ctx->num_transfer_syntaxes < 1) {
1393 return NT_STATUS_INTERNAL_ERROR;
1396 return NT_STATUS_INTERNAL_ERROR;
1398 if (supported_transfer == NULL) {
1399 return NT_STATUS_INTERNAL_ERROR;
1402 switch (ack->result) {
1403 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1404 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1406 * We is already completed.
1408 return NT_STATUS_OK;
1413 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1414 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1416 if_version = ctx->abstract_syntax.if_version;
1417 uuid = ctx->abstract_syntax.uuid;
1419 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1420 if (iface == NULL) {
1421 char *uuid_str = GUID_string(call, &uuid);
1422 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1423 talloc_free(uuid_str);
1425 * We report this only via ack->result
1427 return NT_STATUS_OK;
1430 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1431 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1433 if (validate_only) {
1435 * We report this only via ack->result
1437 return NT_STATUS_OK;
1440 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1442 * we only do NDR encoded dcerpc for now.
1444 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1445 supported_transfer);
1447 selected_transfer = supported_transfer;
1452 context = dcesrv_find_context(call->conn, ctx->context_id);
1453 if (context != NULL) {
1454 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1455 &ctx->abstract_syntax);
1457 return NT_STATUS_RPC_PROTOCOL_ERROR;
1460 if (selected_transfer != NULL) {
1461 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1464 return NT_STATUS_RPC_PROTOCOL_ERROR;
1467 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1468 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1469 ack->syntax = context->transfer_syntax;
1473 * We report this only via ack->result
1475 return NT_STATUS_OK;
1478 if (selected_transfer == NULL) {
1480 * We report this only via ack->result
1482 return NT_STATUS_OK;
1485 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1486 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1488 /* add this context to the list of available context_ids */
1489 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1490 if (context == NULL) {
1491 return NT_STATUS_NO_MEMORY;
1493 context->conn = call->conn;
1494 context->context_id = ctx->context_id;
1495 context->iface = iface;
1496 context->transfer_syntax = *selected_transfer;
1497 context->private_data = NULL;
1498 DLIST_ADD(call->conn->contexts, context);
1499 call->context = context;
1500 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1502 dcesrv_prepare_context_auth(call);
1505 * Multiplex is supported by default
1507 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1509 status = iface->bind(call, iface, if_version);
1510 call->context = NULL;
1511 if (!NT_STATUS_IS_OK(status)) {
1512 /* we don't want to trigger the iface->unbind() hook */
1513 context->iface = NULL;
1514 talloc_free(context);
1516 * We report this only via ack->result
1518 return NT_STATUS_OK;
1521 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1522 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1523 ack->syntax = context->transfer_syntax;
1524 return NT_STATUS_OK;
1527 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1528 const struct dcerpc_bind *b,
1529 struct dcerpc_ack_ctx *ack_ctx_list)
1533 bool validate_only = false;
1534 bool preferred_ndr32;
1537 * Try to negotiate one new presentation context,
1538 * using our preferred transfer syntax.
1540 for (i = 0; i < b->num_contexts; i++) {
1541 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1542 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1544 status = dcesrv_check_or_create_context(call, b, c, a,
1546 call->conn->preferred_transfer);
1547 if (!NT_STATUS_IS_OK(status)) {
1551 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1553 * We managed to negotiate one context.
1557 validate_only = true;
1561 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1562 call->conn->preferred_transfer);
1563 if (preferred_ndr32) {
1567 return NT_STATUS_OK;
1571 * Try to negotiate one new presentation context,
1572 * using NDR 32 as fallback.
1574 for (i = 0; i < b->num_contexts; i++) {
1575 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1576 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1578 status = dcesrv_check_or_create_context(call, b, c, a,
1580 &ndr_transfer_syntax_ndr);
1581 if (!NT_STATUS_IS_OK(status)) {
1585 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1587 * We managed to negotiate one context.
1591 validate_only = true;
1595 return NT_STATUS_OK;
1598 static void dcesrv_alter_done(struct tevent_req *subreq);
1601 handle a alter context request
1603 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1605 struct dcesrv_connection *conn = call->conn;
1607 bool auth_ok = false;
1608 struct ncacn_packet *pkt = &call->ack_pkt;
1609 uint32_t extra_flags = 0;
1610 struct dcesrv_auth *auth = &call->conn->auth_state;
1611 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1612 struct tevent_req *subreq = NULL;
1615 if (!call->conn->allow_alter) {
1616 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1619 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1621 call->pkt.u.alter.auth_info.length,
1622 0, /* required flags */
1623 DCERPC_PFC_FLAG_FIRST |
1624 DCERPC_PFC_FLAG_LAST |
1625 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1626 0x08 | /* this is not defined, but should be ignored */
1627 DCERPC_PFC_FLAG_CONC_MPX |
1628 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1629 DCERPC_PFC_FLAG_MAYBE |
1630 DCERPC_PFC_FLAG_OBJECT_UUID);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1635 auth_ok = dcesrv_auth_alter(call);
1637 if (call->fault_code != 0) {
1638 return dcesrv_fault_disconnect(call, call->fault_code);
1642 if (call->pkt.u.alter.num_contexts < 1) {
1643 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1646 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1647 call->pkt.u.alter.num_contexts);
1648 if (ack_ctx_list == NULL) {
1649 return NT_STATUS_NO_MEMORY;
1653 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1654 * dcesrv_check_or_create_context()) and do some protocol validation
1655 * and set sane defaults.
1657 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1658 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1659 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1661 if (c->num_transfer_syntaxes == 0) {
1662 return dcesrv_fault_disconnect(call,
1663 DCERPC_NCA_S_PROTO_ERROR);
1666 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1667 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1671 * Try to negotiate one new presentation context.
1673 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1674 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1675 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1677 if (!NT_STATUS_IS_OK(status)) {
1681 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1682 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1683 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1684 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1687 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1688 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1691 /* handle any authentication that is being requested */
1693 if (call->in_auth_info.auth_type !=
1694 call->conn->auth_state.auth_type)
1696 return dcesrv_fault_disconnect(call,
1697 DCERPC_FAULT_SEC_PKG_ERROR);
1699 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1702 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1703 pkt->auth_length = 0;
1704 pkt->call_id = call->pkt.call_id;
1705 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1706 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1707 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1708 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1709 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1710 pkt->u.alter_resp.secondary_address = "";
1711 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1712 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1713 pkt->u.alter_resp.auth_info = data_blob_null;
1715 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1716 if (!NT_STATUS_IS_OK(status)) {
1717 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1720 if (auth->auth_finished) {
1721 return dcesrv_auth_reply(call);
1724 subreq = gensec_update_send(call, call->event_ctx,
1725 auth->gensec_security,
1726 call->in_auth_info.credentials);
1727 if (subreq == NULL) {
1728 return NT_STATUS_NO_MEMORY;
1730 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1732 return dcesrv_conn_auth_wait_setup(conn);
1735 static void dcesrv_alter_done(struct tevent_req *subreq)
1737 struct dcesrv_call_state *call =
1738 tevent_req_callback_data(subreq,
1739 struct dcesrv_call_state);
1740 struct dcesrv_connection *conn = call->conn;
1743 status = gensec_update_recv(subreq, call,
1744 &call->out_auth_info->credentials);
1745 TALLOC_FREE(subreq);
1747 status = dcesrv_auth_complete(call, status);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1750 dcesrv_conn_auth_wait_finished(conn, status);
1754 status = dcesrv_auth_reply(call);
1755 dcesrv_conn_auth_wait_finished(conn, status);
1760 possibly save the call for inspection with ndrdump
1762 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1766 const char *dump_dir;
1767 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1771 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1773 call->context->iface->name,
1774 call->pkt.u.request.opnum,
1776 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1777 DEBUG(0,("RPC SAVED %s\n", fname));
1783 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1785 TALLOC_CTX *frame = talloc_stackframe();
1786 const uint32_t bitmask1 = call->conn->auth_state.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 enum dcerpc_transport_t transport =
1826 dcerpc_binding_get_transport(endpoint->ep_description);
1827 struct ndr_pull *pull;
1830 if (!call->conn->allow_request) {
1831 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1834 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1835 if (call->conn->auth_state.gensec_security &&
1836 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1837 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1840 if (call->context == NULL) {
1841 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1842 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1845 switch (call->conn->auth_state.auth_level) {
1846 case DCERPC_AUTH_LEVEL_NONE:
1847 case DCERPC_AUTH_LEVEL_PACKET:
1848 case DCERPC_AUTH_LEVEL_INTEGRITY:
1849 case DCERPC_AUTH_LEVEL_PRIVACY:
1852 if (!call->context->allow_connect) {
1855 addr = tsocket_address_string(call->conn->remote_address,
1858 DEBUG(2, ("%s: restrict auth_level_connect access "
1859 "to [%s] with auth[type=0x%x,level=0x%x] "
1860 "on [%s] from [%s]\n",
1861 __func__, call->context->iface->name,
1862 call->conn->auth_state.auth_type,
1863 call->conn->auth_state.auth_level,
1864 derpc_transport_string_by_transport(transport),
1866 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1871 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1874 addr = tsocket_address_string(call->conn->remote_address, call);
1876 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1877 "to [%s] with auth[type=0x%x,level=0x%x] "
1878 "on [%s] from [%s]\n",
1880 call->context->min_auth_level,
1881 call->context->iface->name,
1882 call->conn->auth_state.auth_type,
1883 call->conn->auth_state.auth_level,
1884 derpc_transport_string_by_transport(transport),
1886 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1889 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1890 NT_STATUS_HAVE_NO_MEMORY(pull);
1892 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1894 call->ndr_pull = pull;
1896 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1897 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1900 status = dcesrv_check_verification_trailer(call);
1901 if (!NT_STATUS_IS_OK(status)) {
1902 uint32_t faultcode = DCERPC_FAULT_OTHER;
1903 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1904 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1906 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1907 nt_errstr(status)));
1908 return dcesrv_fault(call, faultcode);
1911 /* unravel the NDR for the packet */
1912 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1913 if (!NT_STATUS_IS_OK(status)) {
1914 uint8_t extra_flags = 0;
1915 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1916 /* we got an unknown call */
1917 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1918 call->pkt.u.request.opnum,
1919 call->context->iface->name));
1920 dcesrv_save_call(call, "unknown");
1921 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1923 dcesrv_save_call(call, "pullfail");
1925 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1928 if (pull->offset != pull->data_size) {
1929 dcesrv_save_call(call, "extrabytes");
1930 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1931 pull->data_size - pull->offset));
1934 /* call the dispatch function */
1935 status = call->context->iface->dispatch(call, call, call->r);
1936 if (!NT_STATUS_IS_OK(status)) {
1937 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1938 call->context->iface->name,
1939 call->pkt.u.request.opnum,
1940 dcerpc_errstr(pull, call->fault_code)));
1941 return dcesrv_fault(call, call->fault_code);
1944 /* add the call to the pending list */
1945 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1947 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1948 return NT_STATUS_OK;
1951 return dcesrv_reply(call);
1956 remove the call from the right list when freed
1958 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1960 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1964 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1966 return conn->local_address;
1969 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1971 return conn->remote_address;
1975 process some input to a dcerpc endpoint server.
1977 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1978 struct ncacn_packet *pkt,
1982 struct dcesrv_call_state *call;
1983 struct dcesrv_call_state *existing = NULL;
1985 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1987 data_blob_free(&blob);
1989 return NT_STATUS_NO_MEMORY;
1991 call->conn = dce_conn;
1992 call->event_ctx = dce_conn->event_ctx;
1993 call->msg_ctx = dce_conn->msg_ctx;
1994 call->state_flags = call->conn->state_flags;
1995 call->time = timeval_current();
1996 call->list = DCESRV_LIST_NONE;
1998 talloc_steal(call, pkt);
1999 talloc_steal(call, blob.data);
2002 talloc_set_destructor(call, dcesrv_call_dequeue);
2004 if (call->conn->allow_bind) {
2006 * Only one bind is possible per connection
2008 call->conn->allow_bind = false;
2009 return dcesrv_bind(call);
2012 /* we have to check the signing here, before combining the
2014 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2015 if (!call->conn->allow_request) {
2016 return dcesrv_fault_disconnect(call,
2017 DCERPC_NCA_S_PROTO_ERROR);
2020 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2022 call->pkt.u.request.stub_and_verifier.length,
2023 0, /* required_flags */
2024 DCERPC_PFC_FLAG_FIRST |
2025 DCERPC_PFC_FLAG_LAST |
2026 DCERPC_PFC_FLAG_PENDING_CANCEL |
2027 0x08 | /* this is not defined, but should be ignored */
2028 DCERPC_PFC_FLAG_CONC_MPX |
2029 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2030 DCERPC_PFC_FLAG_MAYBE |
2031 DCERPC_PFC_FLAG_OBJECT_UUID);
2032 if (!NT_STATUS_IS_OK(status)) {
2033 return dcesrv_fault_disconnect(call,
2034 DCERPC_NCA_S_PROTO_ERROR);
2037 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2039 * We don't use dcesrv_fault_disconnect()
2040 * here, because we don't want to set
2041 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2043 * Note that we don't check against the negotiated
2044 * max_recv_frag, but a hard coded value.
2046 dcesrv_call_disconnect_after(call,
2047 "dcesrv_auth_request - frag_length too large");
2048 return dcesrv_fault(call,
2049 DCERPC_NCA_S_PROTO_ERROR);
2052 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2053 if (dce_conn->pending_call_list != NULL) {
2055 * concurrent requests are only allowed
2056 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2058 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2059 dcesrv_call_disconnect_after(call,
2060 "dcesrv_auth_request - "
2061 "existing pending call without CONN_MPX");
2062 return dcesrv_fault(call,
2063 DCERPC_NCA_S_PROTO_ERROR);
2066 /* only one request is possible in the fragmented list */
2067 if (dce_conn->incoming_fragmented_call_list != NULL) {
2068 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2070 * Without DCERPC_PFC_FLAG_CONC_MPX
2071 * we need to return the FAULT on the
2072 * already existing call.
2074 * This is important to get the
2075 * call_id and context_id right.
2078 call = dce_conn->incoming_fragmented_call_list;
2080 dcesrv_call_disconnect_after(call,
2081 "dcesrv_auth_request - "
2082 "existing fragmented call");
2083 return dcesrv_fault(call,
2084 DCERPC_NCA_S_PROTO_ERROR);
2086 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2087 return dcesrv_fault_disconnect(call,
2088 DCERPC_FAULT_NO_CALL_ACTIVE);
2090 call->context = dcesrv_find_context(call->conn,
2091 call->pkt.u.request.context_id);
2092 if (call->context == NULL) {
2093 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2094 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2097 const struct dcerpc_request *nr = &call->pkt.u.request;
2098 const struct dcerpc_request *er = NULL;
2101 existing = dcesrv_find_fragmented_call(dce_conn,
2103 if (existing == NULL) {
2104 dcesrv_call_disconnect_after(call,
2105 "dcesrv_auth_request - "
2106 "no existing fragmented call");
2107 return dcesrv_fault(call,
2108 DCERPC_NCA_S_PROTO_ERROR);
2110 er = &existing->pkt.u.request;
2112 if (call->pkt.ptype != existing->pkt.ptype) {
2113 /* trying to play silly buggers are we? */
2114 return dcesrv_fault_disconnect(existing,
2115 DCERPC_NCA_S_PROTO_ERROR);
2117 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2120 return dcesrv_fault_disconnect(existing,
2121 DCERPC_NCA_S_PROTO_ERROR);
2123 if (nr->context_id != er->context_id) {
2124 return dcesrv_fault_disconnect(existing,
2125 DCERPC_NCA_S_PROTO_ERROR);
2127 if (nr->opnum != er->opnum) {
2128 return dcesrv_fault_disconnect(existing,
2129 DCERPC_NCA_S_PROTO_ERROR);
2134 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2136 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2138 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2139 payload_offset += 16;
2142 ok = dcesrv_auth_pkt_pull(call, &blob,
2143 0, /* required_flags */
2144 DCERPC_PFC_FLAG_FIRST |
2145 DCERPC_PFC_FLAG_LAST |
2146 DCERPC_PFC_FLAG_PENDING_CANCEL |
2147 0x08 | /* this is not defined, but should be ignored */
2148 DCERPC_PFC_FLAG_CONC_MPX |
2149 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2150 DCERPC_PFC_FLAG_MAYBE |
2151 DCERPC_PFC_FLAG_OBJECT_UUID,
2153 &call->pkt.u.request.stub_and_verifier);
2156 * We don't use dcesrv_fault_disconnect()
2157 * here, because we don't want to set
2158 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2160 dcesrv_call_disconnect_after(call,
2161 "dcesrv_auth_request - failed");
2162 if (call->fault_code == 0) {
2163 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2165 return dcesrv_fault(call, call->fault_code);
2169 /* see if this is a continued packet */
2170 if (existing != NULL) {
2171 struct dcerpc_request *er = &existing->pkt.u.request;
2172 const struct dcerpc_request *nr = &call->pkt.u.request;
2178 * Up to 4 MByte are allowed by all fragments
2180 available = dce_conn->max_total_request_size;
2181 if (er->stub_and_verifier.length > available) {
2182 dcesrv_call_disconnect_after(existing,
2183 "dcesrv_auth_request - existing payload too large");
2184 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2186 available -= er->stub_and_verifier.length;
2187 if (nr->alloc_hint > available) {
2188 dcesrv_call_disconnect_after(existing,
2189 "dcesrv_auth_request - alloc hint too large");
2190 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2192 if (nr->stub_and_verifier.length > available) {
2193 dcesrv_call_disconnect_after(existing,
2194 "dcesrv_auth_request - new payload too large");
2195 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2197 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2198 /* allocate at least 1 byte */
2199 alloc_hint = MAX(alloc_hint, 1);
2200 alloc_size = er->stub_and_verifier.length +
2201 nr->stub_and_verifier.length;
2202 alloc_size = MAX(alloc_size, alloc_hint);
2204 er->stub_and_verifier.data =
2205 talloc_realloc(existing,
2206 er->stub_and_verifier.data,
2207 uint8_t, alloc_size);
2208 if (er->stub_and_verifier.data == NULL) {
2210 return dcesrv_fault_with_flags(existing,
2211 DCERPC_FAULT_OUT_OF_RESOURCES,
2212 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2214 memcpy(er->stub_and_verifier.data +
2215 er->stub_and_verifier.length,
2216 nr->stub_and_verifier.data,
2217 nr->stub_and_verifier.length);
2218 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2220 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2226 /* this may not be the last pdu in the chain - if its isn't then
2227 just put it on the incoming_fragmented_call_list and wait for the rest */
2228 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2229 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2231 * Up to 4 MByte are allowed by all fragments
2233 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2234 dcesrv_call_disconnect_after(call,
2235 "dcesrv_auth_request - initial alloc hint too large");
2236 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2238 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2239 return NT_STATUS_OK;
2242 /* This removes any fragments we may have had stashed away */
2243 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2245 switch (call->pkt.ptype) {
2246 case DCERPC_PKT_BIND:
2247 status = dcesrv_bind_nak(call,
2248 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2250 case DCERPC_PKT_AUTH3:
2251 status = dcesrv_auth3(call);
2253 case DCERPC_PKT_ALTER:
2254 status = dcesrv_alter(call);
2256 case DCERPC_PKT_REQUEST:
2257 status = dcesrv_request(call);
2259 case DCERPC_PKT_CO_CANCEL:
2260 case DCERPC_PKT_ORPHANED:
2262 * Window just ignores CO_CANCEL and ORPHANED,
2265 status = NT_STATUS_OK;
2268 case DCERPC_PKT_BIND_ACK:
2269 case DCERPC_PKT_BIND_NAK:
2270 case DCERPC_PKT_ALTER_RESP:
2271 case DCERPC_PKT_RESPONSE:
2272 case DCERPC_PKT_FAULT:
2273 case DCERPC_PKT_SHUTDOWN:
2275 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2279 /* if we are going to be sending a reply then add
2280 it to the list of pending calls. We add it to the end to keep the call
2281 list in the order we will answer */
2282 if (!NT_STATUS_IS_OK(status)) {
2289 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2290 struct loadparm_context *lp_ctx,
2291 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2294 struct dcesrv_context *dce_ctx;
2297 if (!endpoint_servers) {
2298 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2299 return NT_STATUS_INTERNAL_ERROR;
2302 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2303 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2305 if (uid_wrapper_enabled()) {
2306 setenv("UID_WRAPPER_MYUID", "1", 1);
2308 dce_ctx->initial_euid = geteuid();
2309 if (uid_wrapper_enabled()) {
2310 unsetenv("UID_WRAPPER_MYUID");
2313 dce_ctx->endpoint_list = NULL;
2314 dce_ctx->lp_ctx = lp_ctx;
2315 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2316 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2317 dce_ctx->broken_connections = NULL;
2319 for (i=0;endpoint_servers[i];i++) {
2320 const struct dcesrv_endpoint_server *ep_server;
2322 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2324 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2325 return NT_STATUS_INTERNAL_ERROR;
2328 status = ep_server->init_server(dce_ctx, ep_server);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2331 nt_errstr(status)));
2336 *_dce_ctx = dce_ctx;
2337 return NT_STATUS_OK;
2340 /* the list of currently registered DCERPC endpoint servers.
2342 static struct ep_server {
2343 struct dcesrv_endpoint_server *ep_server;
2344 } *ep_servers = NULL;
2345 static int num_ep_servers;
2348 register a DCERPC endpoint server.
2350 The 'name' can be later used by other backends to find the operations
2351 structure for this backend.
2354 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2357 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2358 /* its already registered! */
2359 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2361 return NT_STATUS_OBJECT_NAME_COLLISION;
2364 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2366 smb_panic("out of memory in dcerpc_register");
2369 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2370 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2374 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2377 return NT_STATUS_OK;
2381 return the operations structure for a named backend of the specified type
2383 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2387 for (i=0;i<num_ep_servers;i++) {
2388 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2389 return ep_servers[i].ep_server;
2396 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2398 static bool initialized;
2399 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2400 STATIC_dcerpc_server_MODULES_PROTO;
2401 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2402 init_module_fn *shared_init;
2409 shared_init = load_samba_modules(NULL, "dcerpc_server");
2411 run_init_functions(NULL, static_init);
2412 run_init_functions(NULL, shared_init);
2414 talloc_free(shared_init);
2418 return the DCERPC module version, and the size of some critical types
2419 This can be used by endpoint server modules to either detect compilation errors, or provide
2420 multiple implementations for different smbd compilation options in one module
2422 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2424 static const struct dcesrv_critical_sizes critical_sizes = {
2425 DCERPC_MODULE_VERSION,
2426 sizeof(struct dcesrv_context),
2427 sizeof(struct dcesrv_endpoint),
2428 sizeof(struct dcesrv_endpoint_server),
2429 sizeof(struct dcesrv_interface),
2430 sizeof(struct dcesrv_if_list),
2431 sizeof(struct dcesrv_connection),
2432 sizeof(struct dcesrv_call_state),
2433 sizeof(struct dcesrv_auth),
2434 sizeof(struct dcesrv_handle)
2437 return &critical_sizes;
2440 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2442 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2443 struct stream_connection *srv_conn;
2444 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2445 struct stream_connection);
2447 dce_conn->wait_send = NULL;
2448 dce_conn->wait_recv = NULL;
2449 dce_conn->wait_private = NULL;
2451 dce_conn->allow_bind = false;
2452 dce_conn->allow_auth3 = false;
2453 dce_conn->allow_alter = false;
2454 dce_conn->allow_request = false;
2456 if (dce_conn->pending_call_list == NULL) {
2457 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2459 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2460 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2464 if (dce_conn->terminate != NULL) {
2468 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2470 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2471 if (dce_conn->terminate == NULL) {
2472 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2474 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2477 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2479 struct dcesrv_connection *cur, *next;
2481 next = dce_ctx->broken_connections;
2482 while (next != NULL) {
2486 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2487 struct dcesrv_connection_context *context_cur, *context_next;
2489 context_next = cur->contexts;
2490 while (context_next != NULL) {
2491 context_cur = context_next;
2492 context_next = context_cur->next;
2494 dcesrv_connection_context_destructor(context_cur);
2498 dcesrv_terminate_connection(cur, cur->terminate);
2502 /* We need this include to be able to compile on some plateforms
2503 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2505 * It has to be that deep because otherwise we have a conflict on
2506 * const struct dcesrv_interface declaration.
2507 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2508 * which conflict with the bind used before.
2510 #include "system/network.h"
2512 struct dcesrv_sock_reply_state {
2513 struct dcesrv_connection *dce_conn;
2514 struct dcesrv_call_state *call;
2518 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2519 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2521 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2523 struct dcesrv_call_state *call;
2525 call = dce_conn->call_list;
2526 if (!call || !call->replies) {
2530 while (call->replies) {
2531 struct data_blob_list_item *rep = call->replies;
2532 struct dcesrv_sock_reply_state *substate;
2533 struct tevent_req *subreq;
2535 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2537 dcesrv_terminate_connection(dce_conn, "no memory");
2541 substate->dce_conn = dce_conn;
2542 substate->call = NULL;
2544 DLIST_REMOVE(call->replies, rep);
2546 if (call->replies == NULL && call->terminate_reason == NULL) {
2547 substate->call = call;
2550 substate->iov.iov_base = (void *) rep->blob.data;
2551 substate->iov.iov_len = rep->blob.length;
2553 subreq = tstream_writev_queue_send(substate,
2554 dce_conn->event_ctx,
2556 dce_conn->send_queue,
2559 dcesrv_terminate_connection(dce_conn, "no memory");
2562 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2566 if (call->terminate_reason != NULL) {
2567 struct tevent_req *subreq;
2569 subreq = tevent_queue_wait_send(call,
2570 dce_conn->event_ctx,
2571 dce_conn->send_queue);
2573 dcesrv_terminate_connection(dce_conn, __location__);
2576 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2580 DLIST_REMOVE(call->conn->call_list, call);
2581 call->list = DCESRV_LIST_NONE;
2584 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2586 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2587 struct dcesrv_sock_reply_state);
2591 struct dcesrv_call_state *call = substate->call;
2593 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2594 TALLOC_FREE(subreq);
2596 status = map_nt_error_from_unix_common(sys_errno);
2597 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2601 talloc_free(substate);
2607 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2609 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2611 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2612 struct dcesrv_call_state);
2616 /* make sure we stop send queue before removing subreq */
2617 tevent_queue_stop(call->conn->send_queue);
2619 ok = tevent_queue_wait_recv(subreq);
2620 TALLOC_FREE(subreq);
2622 dcesrv_terminate_connection(call->conn, __location__);
2626 /* disconnect after 200 usecs */
2627 tv = timeval_current_ofs_usec(200);
2628 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2629 if (subreq == NULL) {
2630 dcesrv_terminate_connection(call->conn, __location__);
2633 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2637 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2639 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2640 struct dcesrv_call_state);
2643 ok = tevent_wakeup_recv(subreq);
2644 TALLOC_FREE(subreq);
2646 dcesrv_terminate_connection(call->conn, __location__);
2650 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2653 struct dcesrv_socket_context {
2654 const struct dcesrv_endpoint *endpoint;
2655 struct dcesrv_context *dcesrv_ctx;
2659 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2661 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2664 struct dcesrv_socket_context *dcesrv_sock =
2665 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2666 enum dcerpc_transport_t transport =
2667 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2668 struct dcesrv_connection *dcesrv_conn = NULL;
2670 struct tevent_req *subreq;
2671 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2673 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2675 if (!srv_conn->session_info) {
2676 status = auth_anonymous_session_info(srv_conn,
2678 &srv_conn->session_info);
2679 if (!NT_STATUS_IS_OK(status)) {
2680 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2681 nt_errstr(status)));
2682 stream_terminate_connection(srv_conn, nt_errstr(status));
2688 * This fills in dcesrv_conn->endpoint with the endpoint
2689 * associated with the socket. From this point on we know
2690 * which (group of) services we are handling, but not the
2691 * specific interface.
2694 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2696 dcesrv_sock->endpoint,
2697 srv_conn->session_info,
2698 srv_conn->event.ctx,
2700 srv_conn->server_id,
2701 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2703 if (!NT_STATUS_IS_OK(status)) {
2704 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2705 nt_errstr(status)));
2706 stream_terminate_connection(srv_conn, nt_errstr(status));
2710 dcesrv_conn->transport.private_data = srv_conn;
2711 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2713 TALLOC_FREE(srv_conn->event.fde);
2715 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2716 if (!dcesrv_conn->send_queue) {
2717 status = NT_STATUS_NO_MEMORY;
2718 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2719 nt_errstr(status)));
2720 stream_terminate_connection(srv_conn, nt_errstr(status));
2724 if (transport == NCACN_NP) {
2725 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2726 &srv_conn->tstream);
2728 ret = tstream_bsd_existing_socket(dcesrv_conn,
2729 socket_get_fd(srv_conn->socket),
2730 &dcesrv_conn->stream);
2732 status = map_nt_error_from_unix_common(errno);
2733 DEBUG(0, ("dcesrv_sock_accept: "
2734 "failed to setup tstream: %s\n",
2735 nt_errstr(status)));
2736 stream_terminate_connection(srv_conn, nt_errstr(status));
2739 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2742 dcesrv_conn->local_address = srv_conn->local_address;
2743 dcesrv_conn->remote_address = srv_conn->remote_address;
2745 if (transport == NCALRPC) {
2750 sock_fd = socket_get_fd(srv_conn->socket);
2751 if (sock_fd == -1) {
2752 stream_terminate_connection(
2753 srv_conn, "socket_get_fd failed\n");
2757 ret = getpeereid(sock_fd, &uid, &gid);
2759 status = map_nt_error_from_unix_common(errno);
2760 DEBUG(0, ("dcesrv_sock_accept: "
2761 "getpeereid() failed for NCALRPC: %s\n",
2762 nt_errstr(status)));
2763 stream_terminate_connection(srv_conn, nt_errstr(status));
2766 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2767 struct tsocket_address *r = NULL;
2769 ret = tsocket_address_unix_from_path(dcesrv_conn,
2770 AS_SYSTEM_MAGIC_PATH_TOKEN,
2773 status = map_nt_error_from_unix_common(errno);
2774 DEBUG(0, ("dcesrv_sock_accept: "
2775 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2776 nt_errstr(status)));
2777 stream_terminate_connection(srv_conn, nt_errstr(status));
2780 dcesrv_conn->remote_address = r;
2784 srv_conn->private_data = dcesrv_conn;
2786 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2787 dcesrv_conn->event_ctx,
2788 dcesrv_conn->stream);
2790 status = NT_STATUS_NO_MEMORY;
2791 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2792 nt_errstr(status)));
2793 stream_terminate_connection(srv_conn, nt_errstr(status));
2796 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2801 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2803 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2805 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2806 struct dcesrv_connection);
2807 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2808 struct ncacn_packet *pkt;
2812 if (dce_conn->terminate) {
2814 * if the current connection is broken
2815 * we need to clean it up before any other connection
2817 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2818 dcesrv_cleanup_broken_connections(dce_ctx);
2822 dcesrv_cleanup_broken_connections(dce_ctx);
2824 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2826 TALLOC_FREE(subreq);
2827 if (!NT_STATUS_IS_OK(status)) {
2828 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2832 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2833 if (!NT_STATUS_IS_OK(status)) {
2834 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2839 * This is used to block the connection during
2840 * pending authentication.
2842 if (dce_conn->wait_send != NULL) {
2843 subreq = dce_conn->wait_send(dce_conn,
2844 dce_conn->event_ctx,
2845 dce_conn->wait_private);
2847 status = NT_STATUS_NO_MEMORY;
2848 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2851 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2855 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2856 dce_conn->event_ctx,
2859 status = NT_STATUS_NO_MEMORY;
2860 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2863 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2866 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2868 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2869 struct dcesrv_connection);
2870 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2873 if (dce_conn->terminate) {
2875 * if the current connection is broken
2876 * we need to clean it up before any other connection
2878 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2879 dcesrv_cleanup_broken_connections(dce_ctx);
2883 dcesrv_cleanup_broken_connections(dce_ctx);
2885 status = dce_conn->wait_recv(subreq);
2886 dce_conn->wait_send = NULL;
2887 dce_conn->wait_recv = NULL;
2888 dce_conn->wait_private = NULL;
2889 TALLOC_FREE(subreq);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2895 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2896 dce_conn->event_ctx,
2899 status = NT_STATUS_NO_MEMORY;
2900 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2903 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2906 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2908 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2909 struct dcesrv_connection);
2910 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2913 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2915 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2916 struct dcesrv_connection);
2917 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2921 static const struct stream_server_ops dcesrv_stream_ops = {
2923 .accept_connection = dcesrv_sock_accept,
2924 .recv_handler = dcesrv_sock_recv,
2925 .send_handler = dcesrv_sock_send,
2928 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2929 struct loadparm_context *lp_ctx,
2930 struct dcesrv_endpoint *e,
2931 struct tevent_context *event_ctx,
2932 const struct model_ops *model_ops,
2933 void *process_context)
2935 struct dcesrv_socket_context *dcesrv_sock;
2938 const char *endpoint;
2940 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2941 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2943 /* remember the endpoint of this socket */
2944 dcesrv_sock->endpoint = e;
2945 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2947 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2949 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2950 model_ops, &dcesrv_stream_ops,
2951 "unix", endpoint, &port,
2952 lpcfg_socket_options(lp_ctx),
2953 dcesrv_sock, process_context);
2954 if (!NT_STATUS_IS_OK(status)) {
2955 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2956 endpoint, nt_errstr(status)));
2962 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2963 struct loadparm_context *lp_ctx,
2964 struct dcesrv_endpoint *e,
2965 struct tevent_context *event_ctx,
2966 const struct model_ops *model_ops,
2967 void *process_context)
2969 struct dcesrv_socket_context *dcesrv_sock;
2973 const char *endpoint;
2975 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2977 if (endpoint == NULL) {
2979 * No identifier specified: use DEFAULT.
2981 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2982 * no endpoint and let the epmapper worry about it.
2984 endpoint = "DEFAULT";
2985 status = dcerpc_binding_set_string_option(e->ep_description,
2988 if (!NT_STATUS_IS_OK(status)) {
2989 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2990 nt_errstr(status)));
2995 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2998 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2999 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3001 /* remember the endpoint of this socket */
3002 dcesrv_sock->endpoint = e;
3003 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3005 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3006 model_ops, &dcesrv_stream_ops,
3007 "unix", full_path, &port,
3008 lpcfg_socket_options(lp_ctx),
3009 dcesrv_sock, process_context);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3012 endpoint, full_path, nt_errstr(status)));
3017 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3018 struct loadparm_context *lp_ctx,
3019 struct dcesrv_endpoint *e,
3020 struct tevent_context *event_ctx,
3021 const struct model_ops *model_ops,
3022 void *process_context)
3024 struct dcesrv_socket_context *dcesrv_sock;
3026 const char *endpoint;
3028 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3029 if (endpoint == NULL) {
3030 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3031 return NT_STATUS_INVALID_PARAMETER;
3034 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3035 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3037 /* remember the endpoint of this socket */
3038 dcesrv_sock->endpoint = e;
3039 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3041 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3042 model_ops, &dcesrv_stream_ops,
3044 dcesrv_sock, process_context);
3045 if (!NT_STATUS_IS_OK(status)) {
3046 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3047 endpoint, nt_errstr(status)));
3051 return NT_STATUS_OK;
3055 add a socket address to the list of events, one event per dcerpc endpoint
3057 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3058 struct dcesrv_endpoint *e,
3059 struct tevent_context *event_ctx,
3060 const struct model_ops *model_ops,
3061 const char *address,
3062 void *process_context)
3064 struct dcesrv_socket_context *dcesrv_sock;
3067 const char *endpoint;
3070 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3071 if (endpoint != NULL) {
3072 port = atoi(endpoint);
3075 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3076 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3078 /* remember the endpoint of this socket */
3079 dcesrv_sock->endpoint = e;
3080 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3082 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3083 model_ops, &dcesrv_stream_ops,
3084 "ip", address, &port,
3085 lpcfg_socket_options(dce_ctx->lp_ctx),
3086 dcesrv_sock, process_context);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 struct dcesrv_if_list *iface;
3089 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3091 for (iface = e->interface_list; iface; iface = iface->next) {
3092 DEBUGADD(0, ("%s ", iface->iface.name));
3094 DEBUGADD(0, ("failed - %s",
3095 nt_errstr(status)));
3099 snprintf(port_str, sizeof(port_str), "%u", port);
3101 status = dcerpc_binding_set_string_option(e->ep_description,
3102 "endpoint", port_str);
3103 if (!NT_STATUS_IS_OK(status)) {
3104 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3105 port_str, nt_errstr(status)));
3108 struct dcesrv_if_list *iface;
3109 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3110 address, port_str));
3111 for (iface = e->interface_list; iface; iface = iface->next) {
3112 DEBUGADD(4, ("%s ", iface->iface.name));
3114 DEBUGADD(4, ("\n"));
3117 return NT_STATUS_OK;
3120 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3122 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3123 struct loadparm_context *lp_ctx,
3124 struct dcesrv_endpoint *e,
3125 struct tevent_context *event_ctx,
3126 const struct model_ops *model_ops,
3127 void *process_context)
3131 /* Add TCP/IP sockets */
3132 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3135 struct interface *ifaces;
3137 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3139 num_interfaces = iface_list_count(ifaces);
3140 for(i = 0; i < num_interfaces; i++) {
3141 const char *address = iface_list_n_ip(ifaces, i);
3142 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3145 NT_STATUS_NOT_OK_RETURN(status);
3150 size_t num_binds = 0;
3151 wcard = iface_list_wildcard(dce_ctx);
3152 NT_STATUS_HAVE_NO_MEMORY(wcard);
3153 for (i=0; wcard[i]; i++) {
3154 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3155 model_ops, wcard[i],
3157 if (NT_STATUS_IS_OK(status)) {
3162 if (num_binds == 0) {
3163 return NT_STATUS_INVALID_PARAMETER_MIX;
3167 return NT_STATUS_OK;
3170 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3171 struct loadparm_context *lp_ctx,
3172 struct dcesrv_endpoint *e,
3173 struct tevent_context *event_ctx,
3174 const struct model_ops *model_ops,
3175 void *process_context)
3177 enum dcerpc_transport_t transport =
3178 dcerpc_binding_get_transport(e->ep_description);
3180 switch (transport) {
3181 case NCACN_UNIX_STREAM:
3182 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3183 model_ops, process_context);
3186 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3187 model_ops, process_context);
3190 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3191 model_ops, process_context);
3194 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3195 model_ops, process_context);
3198 return NT_STATUS_NOT_SUPPORTED;
3204 * retrieve credentials from a dce_call
3206 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3208 return dce_call->conn->auth_state.session_info->credentials;
3212 * returns true if this is an authenticated call
3214 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3216 enum security_user_level level;
3217 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3218 return level >= SECURITY_USER;
3222 * retrieve account_name for a dce_call
3224 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3226 return dce_call->context->conn->auth_state.session_info->info->account_name;
3230 * retrieve session_info from a dce_call
3232 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3234 return dce_call->context->conn->auth_state.session_info;