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, uint16_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;
280 * If we are not using handles, there is no need for force
281 * this service into using a single process.
283 * However, due to the way we listen for RPC packets, we can
284 * only do this if we have a single service per pipe or TCP
285 * port, so we still force a single combined process for
288 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
289 use_single_process = false;
292 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
294 if (NT_STATUS_IS_ERR(status)) {
295 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
299 transport = dcerpc_binding_get_transport(binding);
300 if (transport == NCACN_IP_TCP) {
305 * First check if there is already a port specified, eg
306 * for epmapper on ncacn_ip_tcp:[135]
309 = dcerpc_binding_get_string_option(binding,
311 if (endpoint == NULL) {
312 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
313 "rpc server port", iface->name, 0);
316 * For RPC services that are not set to use a single
317 * process, we do not default to using the 'rpc server
318 * port' because that would cause a double-bind on
321 if (port == 0 && !use_single_process) {
322 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
325 snprintf(port_str, sizeof(port_str), "%u", port);
326 status = dcerpc_binding_set_string_option(binding,
329 if (!NT_STATUS_IS_OK(status)) {
336 /* see if the interface is already registered on the endpoint */
337 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
338 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
339 iface->name, ep_name));
340 return NT_STATUS_OBJECT_NAME_COLLISION;
343 /* check if this endpoint exists
345 ep = find_endpoint(dce_ctx, binding);
349 * We want a new port on ncacn_ip_tcp for NETLOGON, so
350 * it can be multi-process. Other processes can also
351 * listen on distinct ports, if they have one forced
352 * in the code above with eg 'rpc server port:drsuapi = 1027'
354 * If we have mulitiple endpoints on port 0, they each
355 * get an epemeral port (currently by walking up from
358 if (!use_single_process && transport == NCACN_IP_TCP) {
363 if (ep == NULL || add_ep) {
364 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
366 return NT_STATUS_NO_MEMORY;
369 ep->ep_description = talloc_move(ep, &binding);
372 /* add mgmt interface */
373 ifl = talloc_zero(ep, struct dcesrv_if_list);
375 return NT_STATUS_NO_MEMORY;
378 ifl->iface = dcesrv_get_mgmt_interface();
380 DLIST_ADD(ep->interface_list, ifl);
384 * By default don't force into a single process, but if any
385 * interface on this endpoint on this service uses handles
386 * (most do), then we must force into single process mode
388 * By overwriting this each time a new interface is added to
389 * this endpoint, we end up with the most restrictive setting.
391 if (use_single_process) {
392 ep->use_single_process = true;
395 /* talloc a new interface list element */
396 ifl = talloc_zero(ep, struct dcesrv_if_list);
398 return NT_STATUS_NO_MEMORY;
401 /* copy the given interface struct to the one on the endpoints interface list */
402 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
404 /* if we have a security descriptor given,
405 * we should see if we can set it up on the endpoint
408 /* if there's currently no security descriptor given on the endpoint
411 if (ep->sd == NULL) {
412 ep->sd = security_descriptor_copy(ep, sd);
415 /* if now there's no security descriptor given on the endpoint
416 * something goes wrong, either we failed to copy the security descriptor
417 * or there was already one on the endpoint
419 if (ep->sd != NULL) {
420 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
421 " on endpoint '%s'\n",
422 iface->name, ep_name));
423 if (add_ep) free(ep);
425 return NT_STATUS_OBJECT_NAME_COLLISION;
429 /* finally add the interface on the endpoint */
430 DLIST_ADD(ep->interface_list, ifl);
432 /* if it's a new endpoint add it to the dcesrv_context */
434 DLIST_ADD(dce_ctx->endpoint_list, ep);
437 /* Re-get the string as we may have set a port */
438 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
440 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
441 iface->name, ep_string));
442 TALLOC_FREE(ep_string);
447 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
448 DATA_BLOB *session_key)
450 if (p->auth_state.session_info->session_key.length) {
451 *session_key = p->auth_state.session_info->session_key;
454 return NT_STATUS_NO_USER_SESSION_KEY;
458 fetch the user session key - may be default (above) or the SMB session key
460 The key is always truncated to 16 bytes
462 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
463 DATA_BLOB *session_key)
465 NTSTATUS status = p->auth_state.session_key(p, session_key);
466 if (!NT_STATUS_IS_OK(status)) {
470 session_key->length = MIN(session_key->length, 16);
476 connect to a dcerpc endpoint
478 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
480 const struct dcesrv_endpoint *ep,
481 struct auth_session_info *session_info,
482 struct tevent_context *event_ctx,
483 struct imessaging_context *msg_ctx,
484 struct server_id server_id,
485 uint32_t state_flags,
486 struct dcesrv_connection **_p)
488 struct dcesrv_connection *p;
491 return NT_STATUS_ACCESS_DENIED;
494 p = talloc_zero(mem_ctx, struct dcesrv_connection);
495 NT_STATUS_HAVE_NO_MEMORY(p);
497 if (!talloc_reference(p, session_info)) {
499 return NT_STATUS_NO_MEMORY;
502 p->dce_ctx = dce_ctx;
504 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
505 p->auth_state.session_info = session_info;
506 p->auth_state.session_key = dcesrv_generic_session_key;
507 p->event_ctx = event_ctx;
508 p->msg_ctx = msg_ctx;
509 p->server_id = server_id;
510 p->state_flags = state_flags;
511 p->allow_bind = true;
512 p->max_recv_frag = 5840;
513 p->max_xmit_frag = 5840;
514 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
517 * For now we only support NDR32.
519 p->preferred_transfer = &ndr_transfer_syntax_ndr;
526 move a call from an existing linked list to the specified list. This
527 prevents bugs where we forget to remove the call from a previous
530 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
531 enum dcesrv_call_list list)
533 switch (call->list) {
534 case DCESRV_LIST_NONE:
536 case DCESRV_LIST_CALL_LIST:
537 DLIST_REMOVE(call->conn->call_list, call);
539 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
540 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
542 case DCESRV_LIST_PENDING_CALL_LIST:
543 DLIST_REMOVE(call->conn->pending_call_list, call);
548 case DCESRV_LIST_NONE:
550 case DCESRV_LIST_CALL_LIST:
551 DLIST_ADD_END(call->conn->call_list, call);
553 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
554 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
556 case DCESRV_LIST_PENDING_CALL_LIST:
557 DLIST_ADD_END(call->conn->pending_call_list, call);
562 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
565 if (call->conn->terminate != NULL) {
569 call->conn->allow_bind = false;
570 call->conn->allow_alter = false;
571 call->conn->allow_auth3 = false;
572 call->conn->allow_request = false;
574 call->terminate_reason = talloc_strdup(call, reason);
575 if (call->terminate_reason == NULL) {
576 call->terminate_reason = __location__;
581 return a dcerpc bind_nak
583 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
585 struct ncacn_packet pkt;
586 struct dcerpc_bind_nak_version version;
587 struct data_blob_list_item *rep;
589 static const uint8_t _pad[3] = { 0, };
592 * We add the call to the pending_call_list
593 * in order to defer the termination.
595 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
597 /* setup a bind_nak */
598 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
600 pkt.call_id = call->pkt.call_id;
601 pkt.ptype = DCERPC_PKT_BIND_NAK;
602 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
603 pkt.u.bind_nak.reject_reason = reason;
604 version.rpc_vers = 5;
605 version.rpc_vers_minor = 0;
606 pkt.u.bind_nak.num_versions = 1;
607 pkt.u.bind_nak.versions = &version;
608 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
610 rep = talloc_zero(call, struct data_blob_list_item);
612 return NT_STATUS_NO_MEMORY;
615 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
616 if (!NT_STATUS_IS_OK(status)) {
620 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
622 DLIST_ADD_END(call->replies, rep);
623 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
625 if (call->conn->call_list && call->conn->call_list->replies) {
626 if (call->conn->transport.report_output_data) {
627 call->conn->transport.report_output_data(call->conn);
634 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
638 * We add the call to the pending_call_list
639 * in order to defer the termination.
641 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
643 return dcesrv_fault_with_flags(call, fault_code,
644 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
647 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
649 DLIST_REMOVE(c->conn->contexts, c);
651 if (c->iface && c->iface->unbind) {
652 c->iface->unbind(c, c->iface);
659 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
661 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
662 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
663 enum dcerpc_transport_t transport =
664 dcerpc_binding_get_transport(endpoint->ep_description);
665 struct dcesrv_connection_context *context = dce_call->context;
666 const struct dcesrv_interface *iface = context->iface;
668 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
670 if (transport == NCALRPC) {
671 context->allow_connect = true;
676 * allow overwrite per interface
677 * allow dcerpc auth level connect:<interface>
679 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
680 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
681 "allow dcerpc auth level connect",
683 context->allow_connect);
686 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
687 const struct dcesrv_interface *iface)
689 if (dce_call->context == NULL) {
690 return NT_STATUS_INTERNAL_ERROR;
694 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
695 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
697 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
701 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
702 const struct dcesrv_interface *iface)
704 if (dce_call->context == NULL) {
705 return NT_STATUS_INTERNAL_ERROR;
708 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
712 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
713 const struct dcesrv_interface *iface)
715 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
716 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
717 enum dcerpc_transport_t transport =
718 dcerpc_binding_get_transport(endpoint->ep_description);
719 struct dcesrv_connection_context *context = dce_call->context;
721 if (context == NULL) {
722 return NT_STATUS_INTERNAL_ERROR;
725 if (transport == NCALRPC) {
726 context->allow_connect = true;
731 * allow overwrite per interface
732 * allow dcerpc auth level connect:<interface>
734 context->allow_connect = false;
735 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
736 "allow dcerpc auth level connect",
738 context->allow_connect);
742 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
743 const struct dcesrv_interface *iface)
745 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
746 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
747 enum dcerpc_transport_t transport =
748 dcerpc_binding_get_transport(endpoint->ep_description);
749 struct dcesrv_connection_context *context = dce_call->context;
751 if (context == NULL) {
752 return NT_STATUS_INTERNAL_ERROR;
755 if (transport == NCALRPC) {
756 context->allow_connect = true;
761 * allow overwrite per interface
762 * allow dcerpc auth level connect:<interface>
764 context->allow_connect = true;
765 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
766 "allow dcerpc auth level connect",
768 context->allow_connect);
772 struct dcesrv_conn_auth_wait_context {
773 struct tevent_req *req;
778 struct dcesrv_conn_auth_wait_state {
782 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
783 struct tevent_context *ev,
786 struct dcesrv_conn_auth_wait_context *auth_wait =
787 talloc_get_type_abort(private_data,
788 struct dcesrv_conn_auth_wait_context);
789 struct tevent_req *req = NULL;
790 struct dcesrv_conn_auth_wait_state *state = NULL;
792 req = tevent_req_create(mem_ctx, &state,
793 struct dcesrv_conn_auth_wait_state);
797 auth_wait->req = req;
799 tevent_req_defer_callback(req, ev);
801 if (!auth_wait->done) {
805 if (tevent_req_nterror(req, auth_wait->status)) {
806 return tevent_req_post(req, ev);
809 tevent_req_done(req);
810 return tevent_req_post(req, ev);
813 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
815 return tevent_req_simple_recv_ntstatus(req);
818 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
820 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
822 if (conn->wait_send != NULL) {
823 return NT_STATUS_INTERNAL_ERROR;
826 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
827 if (auth_wait == NULL) {
828 return NT_STATUS_NO_MEMORY;
831 conn->wait_private = auth_wait;
832 conn->wait_send = dcesrv_conn_auth_wait_send;
833 conn->wait_recv = dcesrv_conn_auth_wait_recv;
837 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
840 struct dcesrv_conn_auth_wait_context *auth_wait =
841 talloc_get_type_abort(conn->wait_private,
842 struct dcesrv_conn_auth_wait_context);
844 auth_wait->done = true;
845 auth_wait->status = status;
847 if (auth_wait->req == NULL) {
851 if (tevent_req_nterror(auth_wait->req, status)) {
855 tevent_req_done(auth_wait->req);
858 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
860 static void dcesrv_bind_done(struct tevent_req *subreq);
863 handle a bind request
865 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
867 struct dcesrv_connection *conn = call->conn;
868 struct ncacn_packet *pkt = &call->ack_pkt;
870 uint32_t extra_flags = 0;
871 uint16_t max_req = 0;
872 uint16_t max_rep = 0;
873 const char *ep_prefix = "";
874 const char *endpoint = NULL;
875 struct dcesrv_auth *auth = &call->conn->auth_state;
876 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
877 struct dcerpc_ack_ctx *ack_features = NULL;
878 struct tevent_req *subreq = NULL;
881 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
883 call->pkt.u.bind.auth_info.length,
884 0, /* required flags */
885 DCERPC_PFC_FLAG_FIRST |
886 DCERPC_PFC_FLAG_LAST |
887 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
888 0x08 | /* this is not defined, but should be ignored */
889 DCERPC_PFC_FLAG_CONC_MPX |
890 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
891 DCERPC_PFC_FLAG_MAYBE |
892 DCERPC_PFC_FLAG_OBJECT_UUID);
893 if (!NT_STATUS_IS_OK(status)) {
894 return dcesrv_bind_nak(call,
895 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
898 /* max_recv_frag and max_xmit_frag result always in the same value! */
899 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
900 call->pkt.u.bind.max_recv_frag);
902 * The values are between 2048 and 5840 tested against Windows 2012R2
903 * via ncacn_ip_tcp on port 135.
905 max_req = MAX(2048, max_req);
906 max_rep = MIN(max_req, call->conn->max_recv_frag);
907 /* They are truncated to an 8 byte boundary. */
910 /* max_recv_frag and max_xmit_frag result always in the same value! */
911 call->conn->max_recv_frag = max_rep;
912 call->conn->max_xmit_frag = max_rep;
915 if provided, check the assoc_group is valid
917 if (call->pkt.u.bind.assoc_group_id != 0) {
918 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
920 call->pkt.u.bind.assoc_group_id);
922 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
923 call->conn->dce_ctx);
927 * The NETLOGON server does not use handles and so
928 * there is no need to support association groups, but
929 * we need to give back a number regardless.
931 * We have to do this when it is not run as a single process,
932 * because then it can't see the other valid association
933 * groups. We handle this genericly for all endpoints not
934 * running in single process mode.
936 * We know which endpoint we are on even before checking the
937 * iface UUID, so for simplicity we enforce the same policy
938 * for all interfaces on the endpoint.
940 * This means that where NETLOGON
941 * shares an endpoint (such as ncalrpc or of 'lsa over
942 * netlogon' is set) we will still check association groups.
946 if (call->conn->assoc_group == NULL &&
947 !call->conn->endpoint->use_single_process) {
948 call->conn->assoc_group
949 = dcesrv_assoc_group_new(call->conn,
950 call->conn->dce_ctx);
952 if (call->conn->assoc_group == NULL) {
953 return dcesrv_bind_nak(call, 0);
956 if (call->pkt.u.bind.num_contexts < 1) {
957 return dcesrv_bind_nak(call, 0);
960 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
961 call->pkt.u.bind.num_contexts);
962 if (ack_ctx_list == NULL) {
963 return dcesrv_bind_nak(call, 0);
967 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
968 * dcesrv_check_or_create_context()) and do some protocol validation
969 * and set sane defaults.
971 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
972 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
973 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
974 bool is_feature = false;
975 uint64_t features = 0;
977 if (c->num_transfer_syntaxes == 0) {
978 return dcesrv_bind_nak(call, 0);
981 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
982 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
985 * It's only treated as bind time feature request, if the first
986 * transfer_syntax matches, all others are ignored.
988 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
994 if (ack_features != NULL) {
996 * Only one bind time feature context is allowed.
998 return dcesrv_bind_nak(call, 0);
1002 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1003 a->reason.negotiate = 0;
1004 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1005 /* not supported yet */
1007 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1008 a->reason.negotiate |=
1009 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1012 call->conn->bind_time_features = a->reason.negotiate;
1016 * Try to negotiate one new presentation context.
1018 * Deep in here we locate the iface (by uuid) that the client
1019 * requested, from the list of interfaces on the
1020 * call->conn->endpoint, and call iface->bind() on that iface.
1022 * call->conn was set up at the accept() of the socket, and
1023 * call->conn->endpoint has a list of interfaces restricted to
1024 * this port or pipe.
1026 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1027 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1028 return dcesrv_bind_nak(call, 0);
1030 if (!NT_STATUS_IS_OK(status)) {
1035 * At this point we still don't know which interface (eg
1036 * netlogon, lsa, drsuapi) the caller requested in this bind!
1037 * The most recently added context is available as the first
1038 * element in the linked list at call->conn->contexts, that is
1039 * call->conn->contexts->iface, but they may not have
1040 * requested one at all!
1043 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1044 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1045 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1046 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1049 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1050 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1054 * After finding the interface and setting up the NDR
1055 * transport negotiation etc, handle any authentication that
1056 * is being requested.
1058 if (!dcesrv_auth_bind(call)) {
1060 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1062 * With DCERPC_AUTH_LEVEL_NONE, we get the
1063 * reject_reason in auth->auth_context_id.
1065 return dcesrv_bind_nak(call, auth->auth_context_id);
1069 * This must a be a temporary failure e.g. talloc or invalid
1070 * configuration, e.g. no machine account.
1072 return dcesrv_bind_nak(call,
1073 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1076 /* setup a bind_ack */
1077 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1078 pkt->auth_length = 0;
1079 pkt->call_id = call->pkt.call_id;
1080 pkt->ptype = DCERPC_PKT_BIND_ACK;
1081 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1082 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1083 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1084 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1086 endpoint = dcerpc_binding_get_string_option(
1087 call->conn->endpoint->ep_description,
1089 if (endpoint == NULL) {
1093 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1095 * TODO: check if this is really needed
1097 * Or if we should fix this in our idl files.
1099 ep_prefix = "\\PIPE\\";
1103 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1106 if (pkt->u.bind_ack.secondary_address == NULL) {
1107 return NT_STATUS_NO_MEMORY;
1109 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1110 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1111 pkt->u.bind_ack.auth_info = data_blob_null;
1113 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1114 if (!NT_STATUS_IS_OK(status)) {
1115 return dcesrv_bind_nak(call, 0);
1118 if (auth->auth_finished) {
1119 return dcesrv_auth_reply(call);
1122 subreq = gensec_update_send(call, call->event_ctx,
1123 auth->gensec_security,
1124 call->in_auth_info.credentials);
1125 if (subreq == NULL) {
1126 return NT_STATUS_NO_MEMORY;
1128 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1130 return dcesrv_conn_auth_wait_setup(conn);
1133 static void dcesrv_bind_done(struct tevent_req *subreq)
1135 struct dcesrv_call_state *call =
1136 tevent_req_callback_data(subreq,
1137 struct dcesrv_call_state);
1138 struct dcesrv_connection *conn = call->conn;
1141 status = gensec_update_recv(subreq, call,
1142 &call->out_auth_info->credentials);
1143 TALLOC_FREE(subreq);
1145 status = dcesrv_auth_complete(call, status);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 status = dcesrv_bind_nak(call, 0);
1148 dcesrv_conn_auth_wait_finished(conn, status);
1152 status = dcesrv_auth_reply(call);
1153 dcesrv_conn_auth_wait_finished(conn, status);
1157 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1159 struct ncacn_packet *pkt = &call->ack_pkt;
1160 struct data_blob_list_item *rep = NULL;
1163 rep = talloc_zero(call, struct data_blob_list_item);
1165 return NT_STATUS_NO_MEMORY;
1168 status = ncacn_push_auth(&rep->blob, call, pkt,
1169 call->out_auth_info);
1170 if (!NT_STATUS_IS_OK(status)) {
1174 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1176 DLIST_ADD_END(call->replies, rep);
1177 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1179 if (call->conn->call_list && call->conn->call_list->replies) {
1180 if (call->conn->transport.report_output_data) {
1181 call->conn->transport.report_output_data(call->conn);
1185 return NT_STATUS_OK;
1189 static void dcesrv_auth3_done(struct tevent_req *subreq);
1192 handle a auth3 request
1194 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1196 struct dcesrv_connection *conn = call->conn;
1197 struct dcesrv_auth *auth = &call->conn->auth_state;
1198 struct tevent_req *subreq = NULL;
1201 if (!call->conn->allow_auth3) {
1202 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1205 if (call->conn->auth_state.auth_finished) {
1206 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1209 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1211 call->pkt.u.auth3.auth_info.length,
1212 0, /* required flags */
1213 DCERPC_PFC_FLAG_FIRST |
1214 DCERPC_PFC_FLAG_LAST |
1215 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1216 0x08 | /* this is not defined, but should be ignored */
1217 DCERPC_PFC_FLAG_CONC_MPX |
1218 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1219 DCERPC_PFC_FLAG_MAYBE |
1220 DCERPC_PFC_FLAG_OBJECT_UUID);
1221 if (!NT_STATUS_IS_OK(status)) {
1222 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1225 /* handle the auth3 in the auth code */
1226 if (!dcesrv_auth_prepare_auth3(call)) {
1228 * we don't send a reply to a auth3 request,
1229 * except by a fault.
1231 * In anycase we mark the connection as
1234 call->conn->auth_state.auth_invalid = true;
1235 if (call->fault_code != 0) {
1236 return dcesrv_fault_disconnect(call, call->fault_code);
1239 return NT_STATUS_OK;
1242 subreq = gensec_update_send(call, call->event_ctx,
1243 auth->gensec_security,
1244 call->in_auth_info.credentials);
1245 if (subreq == NULL) {
1246 return NT_STATUS_NO_MEMORY;
1248 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1250 return dcesrv_conn_auth_wait_setup(conn);
1253 static void dcesrv_auth3_done(struct tevent_req *subreq)
1255 struct dcesrv_call_state *call =
1256 tevent_req_callback_data(subreq,
1257 struct dcesrv_call_state);
1258 struct dcesrv_connection *conn = call->conn;
1261 status = gensec_update_recv(subreq, call,
1262 &call->out_auth_info->credentials);
1263 TALLOC_FREE(subreq);
1265 status = dcesrv_auth_complete(call, status);
1266 if (!NT_STATUS_IS_OK(status)) {
1268 * we don't send a reply to a auth3 request,
1269 * except by a fault.
1271 * In anycase we mark the connection as
1274 call->conn->auth_state.auth_invalid = true;
1275 if (call->fault_code != 0) {
1276 status = dcesrv_fault_disconnect(call, call->fault_code);
1277 dcesrv_conn_auth_wait_finished(conn, status);
1281 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1286 * we don't send a reply to a auth3 request.
1289 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1294 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1295 const struct dcerpc_bind *b,
1296 const struct dcerpc_ctx_list *ctx,
1297 struct dcerpc_ack_ctx *ack,
1299 const struct ndr_syntax_id *supported_transfer)
1301 uint32_t if_version;
1302 struct dcesrv_connection_context *context;
1303 const struct dcesrv_interface *iface;
1306 const struct ndr_syntax_id *selected_transfer = NULL;
1311 return NT_STATUS_INTERNAL_ERROR;
1314 return NT_STATUS_INTERNAL_ERROR;
1316 if (ctx->num_transfer_syntaxes < 1) {
1317 return NT_STATUS_INTERNAL_ERROR;
1320 return NT_STATUS_INTERNAL_ERROR;
1322 if (supported_transfer == NULL) {
1323 return NT_STATUS_INTERNAL_ERROR;
1326 switch (ack->result) {
1327 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1328 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1330 * We is already completed.
1332 return NT_STATUS_OK;
1337 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1338 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1340 if_version = ctx->abstract_syntax.if_version;
1341 uuid = ctx->abstract_syntax.uuid;
1343 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1344 if (iface == NULL) {
1345 char *uuid_str = GUID_string(call, &uuid);
1346 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1347 talloc_free(uuid_str);
1349 * We report this only via ack->result
1351 return NT_STATUS_OK;
1354 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1355 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1357 if (validate_only) {
1359 * We report this only via ack->result
1361 return NT_STATUS_OK;
1364 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1366 * we only do NDR encoded dcerpc for now.
1368 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1369 supported_transfer);
1371 selected_transfer = supported_transfer;
1376 context = dcesrv_find_context(call->conn, ctx->context_id);
1377 if (context != NULL) {
1378 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1379 &ctx->abstract_syntax);
1381 return NT_STATUS_RPC_PROTOCOL_ERROR;
1384 if (selected_transfer != NULL) {
1385 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1388 return NT_STATUS_RPC_PROTOCOL_ERROR;
1391 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1392 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1393 ack->syntax = context->transfer_syntax;
1397 * We report this only via ack->result
1399 return NT_STATUS_OK;
1402 if (selected_transfer == NULL) {
1404 * We report this only via ack->result
1406 return NT_STATUS_OK;
1409 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1410 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1412 /* add this context to the list of available context_ids */
1413 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1414 if (context == NULL) {
1415 return NT_STATUS_NO_MEMORY;
1417 context->conn = call->conn;
1418 context->context_id = ctx->context_id;
1419 context->iface = iface;
1420 context->transfer_syntax = *selected_transfer;
1421 context->private_data = NULL;
1422 DLIST_ADD(call->conn->contexts, context);
1423 call->context = context;
1424 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1426 dcesrv_prepare_context_auth(call);
1429 * Multiplex is supported by default
1431 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1433 status = iface->bind(call, iface, if_version);
1434 call->context = NULL;
1435 if (!NT_STATUS_IS_OK(status)) {
1436 /* we don't want to trigger the iface->unbind() hook */
1437 context->iface = NULL;
1438 talloc_free(context);
1440 * We report this only via ack->result
1442 return NT_STATUS_OK;
1445 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1446 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1447 ack->syntax = context->transfer_syntax;
1448 return NT_STATUS_OK;
1451 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1452 const struct dcerpc_bind *b,
1453 struct dcerpc_ack_ctx *ack_ctx_list)
1457 bool validate_only = false;
1458 bool preferred_ndr32;
1461 * Try to negotiate one new presentation context,
1462 * using our preferred transfer syntax.
1464 for (i = 0; i < b->num_contexts; i++) {
1465 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1466 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1468 status = dcesrv_check_or_create_context(call, b, c, a,
1470 call->conn->preferred_transfer);
1471 if (!NT_STATUS_IS_OK(status)) {
1475 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1477 * We managed to negotiate one context.
1481 validate_only = true;
1485 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1486 call->conn->preferred_transfer);
1487 if (preferred_ndr32) {
1491 return NT_STATUS_OK;
1495 * Try to negotiate one new presentation context,
1496 * using NDR 32 as fallback.
1498 for (i = 0; i < b->num_contexts; i++) {
1499 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1500 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1502 status = dcesrv_check_or_create_context(call, b, c, a,
1504 &ndr_transfer_syntax_ndr);
1505 if (!NT_STATUS_IS_OK(status)) {
1509 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1511 * We managed to negotiate one context.
1515 validate_only = true;
1519 return NT_STATUS_OK;
1522 static void dcesrv_alter_done(struct tevent_req *subreq);
1525 handle a alter context request
1527 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1529 struct dcesrv_connection *conn = call->conn;
1531 bool auth_ok = false;
1532 struct ncacn_packet *pkt = &call->ack_pkt;
1533 uint32_t extra_flags = 0;
1534 struct dcesrv_auth *auth = &call->conn->auth_state;
1535 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1536 struct tevent_req *subreq = NULL;
1539 if (!call->conn->allow_alter) {
1540 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1543 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1545 call->pkt.u.alter.auth_info.length,
1546 0, /* required flags */
1547 DCERPC_PFC_FLAG_FIRST |
1548 DCERPC_PFC_FLAG_LAST |
1549 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1550 0x08 | /* this is not defined, but should be ignored */
1551 DCERPC_PFC_FLAG_CONC_MPX |
1552 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1553 DCERPC_PFC_FLAG_MAYBE |
1554 DCERPC_PFC_FLAG_OBJECT_UUID);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1559 auth_ok = dcesrv_auth_alter(call);
1561 if (call->fault_code != 0) {
1562 return dcesrv_fault_disconnect(call, call->fault_code);
1566 if (call->pkt.u.alter.num_contexts < 1) {
1567 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1570 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1571 call->pkt.u.alter.num_contexts);
1572 if (ack_ctx_list == NULL) {
1573 return NT_STATUS_NO_MEMORY;
1577 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1578 * dcesrv_check_or_create_context()) and do some protocol validation
1579 * and set sane defaults.
1581 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1582 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1583 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1585 if (c->num_transfer_syntaxes == 0) {
1586 return dcesrv_fault_disconnect(call,
1587 DCERPC_NCA_S_PROTO_ERROR);
1590 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1591 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1595 * Try to negotiate one new presentation context.
1597 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1598 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1599 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1601 if (!NT_STATUS_IS_OK(status)) {
1605 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1606 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1607 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1608 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1611 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1612 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1615 /* handle any authentication that is being requested */
1617 if (call->in_auth_info.auth_type !=
1618 call->conn->auth_state.auth_type)
1620 return dcesrv_fault_disconnect(call,
1621 DCERPC_FAULT_SEC_PKG_ERROR);
1623 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1626 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1627 pkt->auth_length = 0;
1628 pkt->call_id = call->pkt.call_id;
1629 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1630 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1631 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1632 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1633 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1634 pkt->u.alter_resp.secondary_address = "";
1635 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1636 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1637 pkt->u.alter_resp.auth_info = data_blob_null;
1639 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1640 if (!NT_STATUS_IS_OK(status)) {
1641 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1644 if (auth->auth_finished) {
1645 return dcesrv_auth_reply(call);
1648 subreq = gensec_update_send(call, call->event_ctx,
1649 auth->gensec_security,
1650 call->in_auth_info.credentials);
1651 if (subreq == NULL) {
1652 return NT_STATUS_NO_MEMORY;
1654 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1656 return dcesrv_conn_auth_wait_setup(conn);
1659 static void dcesrv_alter_done(struct tevent_req *subreq)
1661 struct dcesrv_call_state *call =
1662 tevent_req_callback_data(subreq,
1663 struct dcesrv_call_state);
1664 struct dcesrv_connection *conn = call->conn;
1667 status = gensec_update_recv(subreq, call,
1668 &call->out_auth_info->credentials);
1669 TALLOC_FREE(subreq);
1671 status = dcesrv_auth_complete(call, status);
1672 if (!NT_STATUS_IS_OK(status)) {
1673 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1674 dcesrv_conn_auth_wait_finished(conn, status);
1678 status = dcesrv_auth_reply(call);
1679 dcesrv_conn_auth_wait_finished(conn, status);
1684 possibly save the call for inspection with ndrdump
1686 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1690 const char *dump_dir;
1691 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1695 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1697 call->context->iface->name,
1698 call->pkt.u.request.opnum,
1700 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1701 DEBUG(0,("RPC SAVED %s\n", fname));
1707 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1709 TALLOC_CTX *frame = talloc_stackframe();
1710 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1711 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1712 const struct dcerpc_sec_vt_pcontext pcontext = {
1713 .abstract_syntax = call->context->iface->syntax_id,
1714 .transfer_syntax = call->context->transfer_syntax,
1716 const struct dcerpc_sec_vt_header2 header2 =
1717 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1718 enum ndr_err_code ndr_err;
1719 struct dcerpc_sec_verification_trailer *vt = NULL;
1720 NTSTATUS status = NT_STATUS_OK;
1723 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1725 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1727 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1728 status = ndr_map_error2ntstatus(ndr_err);
1732 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1733 &pcontext, &header2);
1735 status = NT_STATUS_ACCESS_DENIED;
1744 handle a dcerpc request packet
1746 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1748 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1749 enum dcerpc_transport_t transport =
1750 dcerpc_binding_get_transport(endpoint->ep_description);
1751 struct ndr_pull *pull;
1754 if (!call->conn->allow_request) {
1755 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1758 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1759 if (call->conn->auth_state.gensec_security &&
1760 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1761 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1764 if (call->context == NULL) {
1765 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1766 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1769 switch (call->conn->auth_state.auth_level) {
1770 case DCERPC_AUTH_LEVEL_NONE:
1771 case DCERPC_AUTH_LEVEL_PACKET:
1772 case DCERPC_AUTH_LEVEL_INTEGRITY:
1773 case DCERPC_AUTH_LEVEL_PRIVACY:
1776 if (!call->context->allow_connect) {
1779 addr = tsocket_address_string(call->conn->remote_address,
1782 DEBUG(2, ("%s: restrict auth_level_connect access "
1783 "to [%s] with auth[type=0x%x,level=0x%x] "
1784 "on [%s] from [%s]\n",
1785 __func__, call->context->iface->name,
1786 call->conn->auth_state.auth_type,
1787 call->conn->auth_state.auth_level,
1788 derpc_transport_string_by_transport(transport),
1790 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1795 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1798 addr = tsocket_address_string(call->conn->remote_address, call);
1800 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1801 "to [%s] with auth[type=0x%x,level=0x%x] "
1802 "on [%s] from [%s]\n",
1804 call->context->min_auth_level,
1805 call->context->iface->name,
1806 call->conn->auth_state.auth_type,
1807 call->conn->auth_state.auth_level,
1808 derpc_transport_string_by_transport(transport),
1810 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1813 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1814 NT_STATUS_HAVE_NO_MEMORY(pull);
1816 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1818 call->ndr_pull = pull;
1820 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1821 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1824 status = dcesrv_check_verification_trailer(call);
1825 if (!NT_STATUS_IS_OK(status)) {
1826 uint32_t faultcode = DCERPC_FAULT_OTHER;
1827 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1828 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1830 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1831 nt_errstr(status)));
1832 return dcesrv_fault(call, faultcode);
1835 /* unravel the NDR for the packet */
1836 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 uint8_t extra_flags = 0;
1839 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1840 /* we got an unknown call */
1841 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1842 call->pkt.u.request.opnum,
1843 call->context->iface->name));
1844 dcesrv_save_call(call, "unknown");
1845 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1847 dcesrv_save_call(call, "pullfail");
1849 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1852 if (pull->offset != pull->data_size) {
1853 dcesrv_save_call(call, "extrabytes");
1854 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1855 pull->data_size - pull->offset));
1858 /* call the dispatch function */
1859 status = call->context->iface->dispatch(call, call, call->r);
1860 if (!NT_STATUS_IS_OK(status)) {
1861 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1862 call->context->iface->name,
1863 call->pkt.u.request.opnum,
1864 dcerpc_errstr(pull, call->fault_code)));
1865 return dcesrv_fault(call, call->fault_code);
1868 /* add the call to the pending list */
1869 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1871 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1872 return NT_STATUS_OK;
1875 return dcesrv_reply(call);
1880 remove the call from the right list when freed
1882 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1884 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1888 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1890 return conn->local_address;
1893 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1895 return conn->remote_address;
1899 process some input to a dcerpc endpoint server.
1901 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1902 struct ncacn_packet *pkt,
1906 struct dcesrv_call_state *call;
1907 struct dcesrv_call_state *existing = NULL;
1909 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1911 data_blob_free(&blob);
1913 return NT_STATUS_NO_MEMORY;
1915 call->conn = dce_conn;
1916 call->event_ctx = dce_conn->event_ctx;
1917 call->msg_ctx = dce_conn->msg_ctx;
1918 call->state_flags = call->conn->state_flags;
1919 call->time = timeval_current();
1920 call->list = DCESRV_LIST_NONE;
1922 talloc_steal(call, pkt);
1923 talloc_steal(call, blob.data);
1926 talloc_set_destructor(call, dcesrv_call_dequeue);
1928 if (call->conn->allow_bind) {
1930 * Only one bind is possible per connection
1932 call->conn->allow_bind = false;
1933 return dcesrv_bind(call);
1936 /* we have to check the signing here, before combining the
1938 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1939 if (!call->conn->allow_request) {
1940 return dcesrv_fault_disconnect(call,
1941 DCERPC_NCA_S_PROTO_ERROR);
1944 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1946 call->pkt.u.request.stub_and_verifier.length,
1947 0, /* required_flags */
1948 DCERPC_PFC_FLAG_FIRST |
1949 DCERPC_PFC_FLAG_LAST |
1950 DCERPC_PFC_FLAG_PENDING_CANCEL |
1951 0x08 | /* this is not defined, but should be ignored */
1952 DCERPC_PFC_FLAG_CONC_MPX |
1953 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1954 DCERPC_PFC_FLAG_MAYBE |
1955 DCERPC_PFC_FLAG_OBJECT_UUID);
1956 if (!NT_STATUS_IS_OK(status)) {
1957 return dcesrv_fault_disconnect(call,
1958 DCERPC_NCA_S_PROTO_ERROR);
1961 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1963 * We don't use dcesrv_fault_disconnect()
1964 * here, because we don't want to set
1965 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1967 * Note that we don't check against the negotiated
1968 * max_recv_frag, but a hard coded value.
1970 dcesrv_call_disconnect_after(call,
1971 "dcesrv_auth_request - frag_length too large");
1972 return dcesrv_fault(call,
1973 DCERPC_NCA_S_PROTO_ERROR);
1976 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1977 if (dce_conn->pending_call_list != NULL) {
1979 * concurrent requests are only allowed
1980 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1982 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1983 dcesrv_call_disconnect_after(call,
1984 "dcesrv_auth_request - "
1985 "existing pending call without CONN_MPX");
1986 return dcesrv_fault(call,
1987 DCERPC_NCA_S_PROTO_ERROR);
1990 /* only one request is possible in the fragmented list */
1991 if (dce_conn->incoming_fragmented_call_list != NULL) {
1992 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1994 * Without DCERPC_PFC_FLAG_CONC_MPX
1995 * we need to return the FAULT on the
1996 * already existing call.
1998 * This is important to get the
1999 * call_id and context_id right.
2002 call = dce_conn->incoming_fragmented_call_list;
2004 dcesrv_call_disconnect_after(call,
2005 "dcesrv_auth_request - "
2006 "existing fragmented call");
2007 return dcesrv_fault(call,
2008 DCERPC_NCA_S_PROTO_ERROR);
2010 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2011 return dcesrv_fault_disconnect(call,
2012 DCERPC_FAULT_NO_CALL_ACTIVE);
2014 call->context = dcesrv_find_context(call->conn,
2015 call->pkt.u.request.context_id);
2016 if (call->context == NULL) {
2017 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2018 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2021 const struct dcerpc_request *nr = &call->pkt.u.request;
2022 const struct dcerpc_request *er = NULL;
2025 existing = dcesrv_find_fragmented_call(dce_conn,
2027 if (existing == NULL) {
2028 dcesrv_call_disconnect_after(call,
2029 "dcesrv_auth_request - "
2030 "no existing fragmented call");
2031 return dcesrv_fault(call,
2032 DCERPC_NCA_S_PROTO_ERROR);
2034 er = &existing->pkt.u.request;
2036 if (call->pkt.ptype != existing->pkt.ptype) {
2037 /* trying to play silly buggers are we? */
2038 return dcesrv_fault_disconnect(existing,
2039 DCERPC_NCA_S_PROTO_ERROR);
2041 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2044 return dcesrv_fault_disconnect(existing,
2045 DCERPC_NCA_S_PROTO_ERROR);
2047 if (nr->context_id != er->context_id) {
2048 return dcesrv_fault_disconnect(existing,
2049 DCERPC_NCA_S_PROTO_ERROR);
2051 if (nr->opnum != er->opnum) {
2052 return dcesrv_fault_disconnect(existing,
2053 DCERPC_NCA_S_PROTO_ERROR);
2058 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2060 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2062 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2063 payload_offset += 16;
2066 ok = dcesrv_auth_pkt_pull(call, &blob,
2067 0, /* required_flags */
2068 DCERPC_PFC_FLAG_FIRST |
2069 DCERPC_PFC_FLAG_LAST |
2070 DCERPC_PFC_FLAG_PENDING_CANCEL |
2071 0x08 | /* this is not defined, but should be ignored */
2072 DCERPC_PFC_FLAG_CONC_MPX |
2073 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2074 DCERPC_PFC_FLAG_MAYBE |
2075 DCERPC_PFC_FLAG_OBJECT_UUID,
2077 &call->pkt.u.request.stub_and_verifier);
2080 * We don't use dcesrv_fault_disconnect()
2081 * here, because we don't want to set
2082 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2084 dcesrv_call_disconnect_after(call,
2085 "dcesrv_auth_request - failed");
2086 if (call->fault_code == 0) {
2087 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2089 return dcesrv_fault(call, call->fault_code);
2093 /* see if this is a continued packet */
2094 if (existing != NULL) {
2095 struct dcerpc_request *er = &existing->pkt.u.request;
2096 const struct dcerpc_request *nr = &call->pkt.u.request;
2102 * Up to 4 MByte are allowed by all fragments
2104 available = dce_conn->max_total_request_size;
2105 if (er->stub_and_verifier.length > available) {
2106 dcesrv_call_disconnect_after(existing,
2107 "dcesrv_auth_request - existing payload too large");
2108 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2110 available -= er->stub_and_verifier.length;
2111 if (nr->alloc_hint > available) {
2112 dcesrv_call_disconnect_after(existing,
2113 "dcesrv_auth_request - alloc hint too large");
2114 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2116 if (nr->stub_and_verifier.length > available) {
2117 dcesrv_call_disconnect_after(existing,
2118 "dcesrv_auth_request - new payload too large");
2119 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2121 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2122 /* allocate at least 1 byte */
2123 alloc_hint = MAX(alloc_hint, 1);
2124 alloc_size = er->stub_and_verifier.length +
2125 nr->stub_and_verifier.length;
2126 alloc_size = MAX(alloc_size, alloc_hint);
2128 er->stub_and_verifier.data =
2129 talloc_realloc(existing,
2130 er->stub_and_verifier.data,
2131 uint8_t, alloc_size);
2132 if (er->stub_and_verifier.data == NULL) {
2134 return dcesrv_fault_with_flags(existing,
2135 DCERPC_FAULT_OUT_OF_RESOURCES,
2136 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2138 memcpy(er->stub_and_verifier.data +
2139 er->stub_and_verifier.length,
2140 nr->stub_and_verifier.data,
2141 nr->stub_and_verifier.length);
2142 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2144 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2150 /* this may not be the last pdu in the chain - if its isn't then
2151 just put it on the incoming_fragmented_call_list and wait for the rest */
2152 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2153 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2155 * Up to 4 MByte are allowed by all fragments
2157 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2158 dcesrv_call_disconnect_after(call,
2159 "dcesrv_auth_request - initial alloc hint too large");
2160 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2162 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2163 return NT_STATUS_OK;
2166 /* This removes any fragments we may have had stashed away */
2167 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2169 switch (call->pkt.ptype) {
2170 case DCERPC_PKT_BIND:
2171 status = dcesrv_bind_nak(call,
2172 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2174 case DCERPC_PKT_AUTH3:
2175 status = dcesrv_auth3(call);
2177 case DCERPC_PKT_ALTER:
2178 status = dcesrv_alter(call);
2180 case DCERPC_PKT_REQUEST:
2181 status = dcesrv_request(call);
2183 case DCERPC_PKT_CO_CANCEL:
2184 case DCERPC_PKT_ORPHANED:
2186 * Window just ignores CO_CANCEL and ORPHANED,
2189 status = NT_STATUS_OK;
2192 case DCERPC_PKT_BIND_ACK:
2193 case DCERPC_PKT_BIND_NAK:
2194 case DCERPC_PKT_ALTER_RESP:
2195 case DCERPC_PKT_RESPONSE:
2196 case DCERPC_PKT_FAULT:
2197 case DCERPC_PKT_SHUTDOWN:
2199 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2203 /* if we are going to be sending a reply then add
2204 it to the list of pending calls. We add it to the end to keep the call
2205 list in the order we will answer */
2206 if (!NT_STATUS_IS_OK(status)) {
2213 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2214 struct loadparm_context *lp_ctx,
2215 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2218 struct dcesrv_context *dce_ctx;
2221 if (!endpoint_servers) {
2222 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2223 return NT_STATUS_INTERNAL_ERROR;
2226 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2227 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2229 if (uid_wrapper_enabled()) {
2230 setenv("UID_WRAPPER_MYUID", "1", 1);
2232 dce_ctx->initial_euid = geteuid();
2233 if (uid_wrapper_enabled()) {
2234 unsetenv("UID_WRAPPER_MYUID");
2237 dce_ctx->endpoint_list = NULL;
2238 dce_ctx->lp_ctx = lp_ctx;
2239 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2240 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2241 dce_ctx->broken_connections = NULL;
2243 for (i=0;endpoint_servers[i];i++) {
2244 const struct dcesrv_endpoint_server *ep_server;
2246 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2248 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2249 return NT_STATUS_INTERNAL_ERROR;
2252 status = ep_server->init_server(dce_ctx, ep_server);
2253 if (!NT_STATUS_IS_OK(status)) {
2254 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2255 nt_errstr(status)));
2260 *_dce_ctx = dce_ctx;
2261 return NT_STATUS_OK;
2264 /* the list of currently registered DCERPC endpoint servers.
2266 static struct ep_server {
2267 struct dcesrv_endpoint_server *ep_server;
2268 } *ep_servers = NULL;
2269 static int num_ep_servers;
2272 register a DCERPC endpoint server.
2274 The 'name' can be later used by other backends to find the operations
2275 structure for this backend.
2278 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2281 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2282 /* its already registered! */
2283 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2285 return NT_STATUS_OBJECT_NAME_COLLISION;
2288 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2290 smb_panic("out of memory in dcerpc_register");
2293 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2294 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2298 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2301 return NT_STATUS_OK;
2305 return the operations structure for a named backend of the specified type
2307 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2311 for (i=0;i<num_ep_servers;i++) {
2312 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2313 return ep_servers[i].ep_server;
2320 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2322 static bool initialized;
2323 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2324 STATIC_dcerpc_server_MODULES_PROTO;
2325 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2326 init_module_fn *shared_init;
2333 shared_init = load_samba_modules(NULL, "dcerpc_server");
2335 run_init_functions(NULL, static_init);
2336 run_init_functions(NULL, shared_init);
2338 talloc_free(shared_init);
2342 return the DCERPC module version, and the size of some critical types
2343 This can be used by endpoint server modules to either detect compilation errors, or provide
2344 multiple implementations for different smbd compilation options in one module
2346 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2348 static const struct dcesrv_critical_sizes critical_sizes = {
2349 DCERPC_MODULE_VERSION,
2350 sizeof(struct dcesrv_context),
2351 sizeof(struct dcesrv_endpoint),
2352 sizeof(struct dcesrv_endpoint_server),
2353 sizeof(struct dcesrv_interface),
2354 sizeof(struct dcesrv_if_list),
2355 sizeof(struct dcesrv_connection),
2356 sizeof(struct dcesrv_call_state),
2357 sizeof(struct dcesrv_auth),
2358 sizeof(struct dcesrv_handle)
2361 return &critical_sizes;
2364 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2366 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2367 struct stream_connection *srv_conn;
2368 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2369 struct stream_connection);
2371 dce_conn->wait_send = NULL;
2372 dce_conn->wait_recv = NULL;
2373 dce_conn->wait_private = NULL;
2375 dce_conn->allow_bind = false;
2376 dce_conn->allow_auth3 = false;
2377 dce_conn->allow_alter = false;
2378 dce_conn->allow_request = false;
2380 if (dce_conn->pending_call_list == NULL) {
2381 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2383 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2384 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2388 if (dce_conn->terminate != NULL) {
2392 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2394 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2395 if (dce_conn->terminate == NULL) {
2396 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2398 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2401 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2403 struct dcesrv_connection *cur, *next;
2405 next = dce_ctx->broken_connections;
2406 while (next != NULL) {
2410 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2411 struct dcesrv_connection_context *context_cur, *context_next;
2413 context_next = cur->contexts;
2414 while (context_next != NULL) {
2415 context_cur = context_next;
2416 context_next = context_cur->next;
2418 dcesrv_connection_context_destructor(context_cur);
2422 dcesrv_terminate_connection(cur, cur->terminate);
2426 /* We need this include to be able to compile on some plateforms
2427 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2429 * It has to be that deep because otherwise we have a conflict on
2430 * const struct dcesrv_interface declaration.
2431 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2432 * which conflict with the bind used before.
2434 #include "system/network.h"
2436 struct dcesrv_sock_reply_state {
2437 struct dcesrv_connection *dce_conn;
2438 struct dcesrv_call_state *call;
2442 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2443 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2445 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2447 struct dcesrv_call_state *call;
2449 call = dce_conn->call_list;
2450 if (!call || !call->replies) {
2454 while (call->replies) {
2455 struct data_blob_list_item *rep = call->replies;
2456 struct dcesrv_sock_reply_state *substate;
2457 struct tevent_req *subreq;
2459 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2461 dcesrv_terminate_connection(dce_conn, "no memory");
2465 substate->dce_conn = dce_conn;
2466 substate->call = NULL;
2468 DLIST_REMOVE(call->replies, rep);
2470 if (call->replies == NULL && call->terminate_reason == NULL) {
2471 substate->call = call;
2474 substate->iov.iov_base = (void *) rep->blob.data;
2475 substate->iov.iov_len = rep->blob.length;
2477 subreq = tstream_writev_queue_send(substate,
2478 dce_conn->event_ctx,
2480 dce_conn->send_queue,
2483 dcesrv_terminate_connection(dce_conn, "no memory");
2486 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2490 if (call->terminate_reason != NULL) {
2491 struct tevent_req *subreq;
2493 subreq = tevent_queue_wait_send(call,
2494 dce_conn->event_ctx,
2495 dce_conn->send_queue);
2497 dcesrv_terminate_connection(dce_conn, __location__);
2500 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2504 DLIST_REMOVE(call->conn->call_list, call);
2505 call->list = DCESRV_LIST_NONE;
2508 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2510 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2511 struct dcesrv_sock_reply_state);
2515 struct dcesrv_call_state *call = substate->call;
2517 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2518 TALLOC_FREE(subreq);
2520 status = map_nt_error_from_unix_common(sys_errno);
2521 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2525 talloc_free(substate);
2531 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2533 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2535 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2536 struct dcesrv_call_state);
2540 /* make sure we stop send queue before removing subreq */
2541 tevent_queue_stop(call->conn->send_queue);
2543 ok = tevent_queue_wait_recv(subreq);
2544 TALLOC_FREE(subreq);
2546 dcesrv_terminate_connection(call->conn, __location__);
2550 /* disconnect after 200 usecs */
2551 tv = timeval_current_ofs_usec(200);
2552 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2553 if (subreq == NULL) {
2554 dcesrv_terminate_connection(call->conn, __location__);
2557 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2561 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2563 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2564 struct dcesrv_call_state);
2567 ok = tevent_wakeup_recv(subreq);
2568 TALLOC_FREE(subreq);
2570 dcesrv_terminate_connection(call->conn, __location__);
2574 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2577 struct dcesrv_socket_context {
2578 const struct dcesrv_endpoint *endpoint;
2579 struct dcesrv_context *dcesrv_ctx;
2583 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2585 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2588 struct dcesrv_socket_context *dcesrv_sock =
2589 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2590 enum dcerpc_transport_t transport =
2591 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2592 struct dcesrv_connection *dcesrv_conn = NULL;
2594 struct tevent_req *subreq;
2595 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2597 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2599 if (!srv_conn->session_info) {
2600 status = auth_anonymous_session_info(srv_conn,
2602 &srv_conn->session_info);
2603 if (!NT_STATUS_IS_OK(status)) {
2604 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2605 nt_errstr(status)));
2606 stream_terminate_connection(srv_conn, nt_errstr(status));
2612 * This fills in dcesrv_conn->endpoint with the endpoint
2613 * associated with the socket. From this point on we know
2614 * which (group of) services we are handling, but not the
2615 * specific interface.
2618 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2620 dcesrv_sock->endpoint,
2621 srv_conn->session_info,
2622 srv_conn->event.ctx,
2624 srv_conn->server_id,
2625 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2627 if (!NT_STATUS_IS_OK(status)) {
2628 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2629 nt_errstr(status)));
2630 stream_terminate_connection(srv_conn, nt_errstr(status));
2634 dcesrv_conn->transport.private_data = srv_conn;
2635 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2637 TALLOC_FREE(srv_conn->event.fde);
2639 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2640 if (!dcesrv_conn->send_queue) {
2641 status = NT_STATUS_NO_MEMORY;
2642 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2643 nt_errstr(status)));
2644 stream_terminate_connection(srv_conn, nt_errstr(status));
2648 if (transport == NCACN_NP) {
2649 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2650 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2651 &srv_conn->tstream);
2653 ret = tstream_bsd_existing_socket(dcesrv_conn,
2654 socket_get_fd(srv_conn->socket),
2655 &dcesrv_conn->stream);
2657 status = map_nt_error_from_unix_common(errno);
2658 DEBUG(0, ("dcesrv_sock_accept: "
2659 "failed to setup tstream: %s\n",
2660 nt_errstr(status)));
2661 stream_terminate_connection(srv_conn, nt_errstr(status));
2664 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2667 dcesrv_conn->local_address = srv_conn->local_address;
2668 dcesrv_conn->remote_address = srv_conn->remote_address;
2670 if (transport == NCALRPC) {
2675 sock_fd = socket_get_fd(srv_conn->socket);
2676 if (sock_fd == -1) {
2677 stream_terminate_connection(
2678 srv_conn, "socket_get_fd failed\n");
2682 ret = getpeereid(sock_fd, &uid, &gid);
2684 status = map_nt_error_from_unix_common(errno);
2685 DEBUG(0, ("dcesrv_sock_accept: "
2686 "getpeereid() failed for NCALRPC: %s\n",
2687 nt_errstr(status)));
2688 stream_terminate_connection(srv_conn, nt_errstr(status));
2691 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2692 struct tsocket_address *r = NULL;
2694 ret = tsocket_address_unix_from_path(dcesrv_conn,
2695 "/root/ncalrpc_as_system",
2698 status = map_nt_error_from_unix_common(errno);
2699 DEBUG(0, ("dcesrv_sock_accept: "
2700 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2701 nt_errstr(status)));
2702 stream_terminate_connection(srv_conn, nt_errstr(status));
2705 dcesrv_conn->remote_address = r;
2709 srv_conn->private_data = dcesrv_conn;
2711 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2713 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2714 dcesrv_conn->event_ctx,
2715 dcesrv_conn->stream);
2717 status = NT_STATUS_NO_MEMORY;
2718 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2719 nt_errstr(status)));
2720 stream_terminate_connection(srv_conn, nt_errstr(status));
2723 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2728 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2730 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2732 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2733 struct dcesrv_connection);
2734 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2735 struct ncacn_packet *pkt;
2739 if (dce_conn->terminate) {
2741 * if the current connection is broken
2742 * we need to clean it up before any other connection
2744 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2745 dcesrv_cleanup_broken_connections(dce_ctx);
2749 dcesrv_cleanup_broken_connections(dce_ctx);
2751 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2753 TALLOC_FREE(subreq);
2754 if (!NT_STATUS_IS_OK(status)) {
2755 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2759 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2760 if (!NT_STATUS_IS_OK(status)) {
2761 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2766 * This is used to block the connection during
2767 * pending authentication.
2769 if (dce_conn->wait_send != NULL) {
2770 subreq = dce_conn->wait_send(dce_conn,
2771 dce_conn->event_ctx,
2772 dce_conn->wait_private);
2774 status = NT_STATUS_NO_MEMORY;
2775 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2778 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2782 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2783 dce_conn->event_ctx,
2786 status = NT_STATUS_NO_MEMORY;
2787 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2790 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2793 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2795 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2796 struct dcesrv_connection);
2797 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2800 if (dce_conn->terminate) {
2802 * if the current connection is broken
2803 * we need to clean it up before any other connection
2805 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2806 dcesrv_cleanup_broken_connections(dce_ctx);
2810 dcesrv_cleanup_broken_connections(dce_ctx);
2812 status = dce_conn->wait_recv(subreq);
2813 dce_conn->wait_send = NULL;
2814 dce_conn->wait_recv = NULL;
2815 dce_conn->wait_private = NULL;
2816 TALLOC_FREE(subreq);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2822 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2823 dce_conn->event_ctx,
2826 status = NT_STATUS_NO_MEMORY;
2827 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2830 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2833 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2835 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2836 struct dcesrv_connection);
2837 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2840 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2842 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2843 struct dcesrv_connection);
2844 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2848 static const struct stream_server_ops dcesrv_stream_ops = {
2850 .accept_connection = dcesrv_sock_accept,
2851 .recv_handler = dcesrv_sock_recv,
2852 .send_handler = dcesrv_sock_send,
2855 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2856 struct loadparm_context *lp_ctx,
2857 struct dcesrv_endpoint *e,
2858 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2860 struct dcesrv_socket_context *dcesrv_sock;
2863 const char *endpoint;
2865 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2866 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2868 /* remember the endpoint of this socket */
2869 dcesrv_sock->endpoint = e;
2870 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2872 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2874 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2875 model_ops, &dcesrv_stream_ops,
2876 "unix", endpoint, &port,
2877 lpcfg_socket_options(lp_ctx),
2879 if (!NT_STATUS_IS_OK(status)) {
2880 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2881 endpoint, nt_errstr(status)));
2887 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2888 struct loadparm_context *lp_ctx,
2889 struct dcesrv_endpoint *e,
2890 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2892 struct dcesrv_socket_context *dcesrv_sock;
2896 const char *endpoint;
2898 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2900 if (endpoint == NULL) {
2902 * No identifier specified: use DEFAULT.
2904 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2905 * no endpoint and let the epmapper worry about it.
2907 endpoint = "DEFAULT";
2908 status = dcerpc_binding_set_string_option(e->ep_description,
2911 if (!NT_STATUS_IS_OK(status)) {
2912 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2913 nt_errstr(status)));
2918 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2921 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2922 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2924 /* remember the endpoint of this socket */
2925 dcesrv_sock->endpoint = e;
2926 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2928 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2929 model_ops, &dcesrv_stream_ops,
2930 "unix", full_path, &port,
2931 lpcfg_socket_options(lp_ctx),
2933 if (!NT_STATUS_IS_OK(status)) {
2934 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2935 endpoint, full_path, nt_errstr(status)));
2940 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2941 struct loadparm_context *lp_ctx,
2942 struct dcesrv_endpoint *e,
2943 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2945 struct dcesrv_socket_context *dcesrv_sock;
2947 const char *endpoint;
2949 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2950 if (endpoint == NULL) {
2951 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2952 return NT_STATUS_INVALID_PARAMETER;
2955 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2956 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2958 /* remember the endpoint of this socket */
2959 dcesrv_sock->endpoint = e;
2960 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2962 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2963 model_ops, &dcesrv_stream_ops,
2966 if (!NT_STATUS_IS_OK(status)) {
2967 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2968 endpoint, nt_errstr(status)));
2972 return NT_STATUS_OK;
2976 add a socket address to the list of events, one event per dcerpc endpoint
2978 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2979 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2980 const char *address)
2982 struct dcesrv_socket_context *dcesrv_sock;
2985 const char *endpoint;
2988 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2989 if (endpoint != NULL) {
2990 port = atoi(endpoint);
2993 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2994 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2996 /* remember the endpoint of this socket */
2997 dcesrv_sock->endpoint = e;
2998 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3000 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3001 model_ops, &dcesrv_stream_ops,
3002 "ip", address, &port,
3003 lpcfg_socket_options(dce_ctx->lp_ctx),
3005 if (!NT_STATUS_IS_OK(status)) {
3006 struct dcesrv_if_list *iface;
3007 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3009 for (iface = e->interface_list; iface; iface = iface->next) {
3010 DEBUGADD(0, ("%s ", iface->iface.name));
3012 DEBUGADD(0, ("failed - %s",
3013 nt_errstr(status)));
3017 snprintf(port_str, sizeof(port_str), "%u", port);
3019 status = dcerpc_binding_set_string_option(e->ep_description,
3020 "endpoint", port_str);
3021 if (!NT_STATUS_IS_OK(status)) {
3022 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3023 port_str, nt_errstr(status)));
3026 struct dcesrv_if_list *iface;
3027 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3028 address, port_str));
3029 for (iface = e->interface_list; iface; iface = iface->next) {
3030 DEBUGADD(4, ("%s ", iface->iface.name));
3032 DEBUGADD(4, ("\n"));
3035 return NT_STATUS_OK;
3038 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3040 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3041 struct loadparm_context *lp_ctx,
3042 struct dcesrv_endpoint *e,
3043 struct tevent_context *event_ctx, const struct model_ops *model_ops)
3047 /* Add TCP/IP sockets */
3048 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3051 struct interface *ifaces;
3053 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3055 num_interfaces = iface_list_count(ifaces);
3056 for(i = 0; i < num_interfaces; i++) {
3057 const char *address = iface_list_n_ip(ifaces, i);
3058 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
3059 NT_STATUS_NOT_OK_RETURN(status);
3065 wcard = iface_list_wildcard(dce_ctx);
3066 NT_STATUS_HAVE_NO_MEMORY(wcard);
3067 for (i=0; wcard[i]; i++) {
3068 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
3069 if (NT_STATUS_IS_OK(status)) {
3074 if (num_binds == 0) {
3075 return NT_STATUS_INVALID_PARAMETER_MIX;
3079 return NT_STATUS_OK;
3082 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3083 struct loadparm_context *lp_ctx,
3084 struct dcesrv_endpoint *e,
3085 struct tevent_context *event_ctx,
3086 const struct model_ops *model_ops)
3088 enum dcerpc_transport_t transport =
3089 dcerpc_binding_get_transport(e->ep_description);
3091 switch (transport) {
3092 case NCACN_UNIX_STREAM:
3093 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3096 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3099 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3102 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3105 return NT_STATUS_NOT_SUPPORTED;
3111 * retrieve credentials from a dce_call
3113 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3115 return dce_call->conn->auth_state.session_info->credentials;
3119 * returns true if this is an authenticated call
3121 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3123 enum security_user_level level;
3124 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3125 return level >= SECURITY_USER;
3129 * retrieve account_name for a dce_call
3131 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3133 return dce_call->context->conn->auth_state.session_info->info->account_name;