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;
1190 handle a auth3 request
1192 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1194 struct dcesrv_auth *auth = &call->conn->auth_state;
1197 if (!call->conn->allow_auth3) {
1198 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1201 if (call->conn->auth_state.auth_finished) {
1202 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1205 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1207 call->pkt.u.auth3.auth_info.length,
1208 0, /* required flags */
1209 DCERPC_PFC_FLAG_FIRST |
1210 DCERPC_PFC_FLAG_LAST |
1211 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1212 0x08 | /* this is not defined, but should be ignored */
1213 DCERPC_PFC_FLAG_CONC_MPX |
1214 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1215 DCERPC_PFC_FLAG_MAYBE |
1216 DCERPC_PFC_FLAG_OBJECT_UUID);
1217 if (!NT_STATUS_IS_OK(status)) {
1218 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1221 /* handle the auth3 in the auth code */
1222 if (!dcesrv_auth_prepare_auth3(call)) {
1224 * we don't send a reply to a auth3 request,
1225 * except by a fault.
1227 * In anycase we mark the connection as
1230 call->conn->auth_state.auth_invalid = true;
1231 if (call->fault_code != 0) {
1232 return dcesrv_fault_disconnect(call, call->fault_code);
1235 return NT_STATUS_OK;
1238 status = gensec_update_ev(auth->gensec_security,
1239 call, call->event_ctx,
1240 call->in_auth_info.credentials,
1241 &call->out_auth_info->credentials);
1243 status = dcesrv_auth_complete(call, status);
1244 if (!NT_STATUS_IS_OK(status)) {
1246 * we don't send a reply to a auth3 request,
1247 * except by a fault.
1249 * In anycase we mark the connection as
1252 call->conn->auth_state.auth_invalid = true;
1253 if (call->fault_code != 0) {
1254 return dcesrv_fault_disconnect(call, call->fault_code);
1257 return NT_STATUS_OK;
1261 * we don't send a reply to a auth3 request.
1264 return NT_STATUS_OK;
1268 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1269 const struct dcerpc_bind *b,
1270 const struct dcerpc_ctx_list *ctx,
1271 struct dcerpc_ack_ctx *ack,
1273 const struct ndr_syntax_id *supported_transfer)
1275 uint32_t if_version;
1276 struct dcesrv_connection_context *context;
1277 const struct dcesrv_interface *iface;
1280 const struct ndr_syntax_id *selected_transfer = NULL;
1285 return NT_STATUS_INTERNAL_ERROR;
1288 return NT_STATUS_INTERNAL_ERROR;
1290 if (ctx->num_transfer_syntaxes < 1) {
1291 return NT_STATUS_INTERNAL_ERROR;
1294 return NT_STATUS_INTERNAL_ERROR;
1296 if (supported_transfer == NULL) {
1297 return NT_STATUS_INTERNAL_ERROR;
1300 switch (ack->result) {
1301 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1302 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1304 * We is already completed.
1306 return NT_STATUS_OK;
1311 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1312 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1314 if_version = ctx->abstract_syntax.if_version;
1315 uuid = ctx->abstract_syntax.uuid;
1317 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1318 if (iface == NULL) {
1319 char *uuid_str = GUID_string(call, &uuid);
1320 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1321 talloc_free(uuid_str);
1323 * We report this only via ack->result
1325 return NT_STATUS_OK;
1328 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1329 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1331 if (validate_only) {
1333 * We report this only via ack->result
1335 return NT_STATUS_OK;
1338 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1340 * we only do NDR encoded dcerpc for now.
1342 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1343 supported_transfer);
1345 selected_transfer = supported_transfer;
1350 context = dcesrv_find_context(call->conn, ctx->context_id);
1351 if (context != NULL) {
1352 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1353 &ctx->abstract_syntax);
1355 return NT_STATUS_RPC_PROTOCOL_ERROR;
1358 if (selected_transfer != NULL) {
1359 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1362 return NT_STATUS_RPC_PROTOCOL_ERROR;
1365 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1366 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1367 ack->syntax = context->transfer_syntax;
1371 * We report this only via ack->result
1373 return NT_STATUS_OK;
1376 if (selected_transfer == NULL) {
1378 * We report this only via ack->result
1380 return NT_STATUS_OK;
1383 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1384 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1386 /* add this context to the list of available context_ids */
1387 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1388 if (context == NULL) {
1389 return NT_STATUS_NO_MEMORY;
1391 context->conn = call->conn;
1392 context->context_id = ctx->context_id;
1393 context->iface = iface;
1394 context->transfer_syntax = *selected_transfer;
1395 context->private_data = NULL;
1396 DLIST_ADD(call->conn->contexts, context);
1397 call->context = context;
1398 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1400 dcesrv_prepare_context_auth(call);
1403 * Multiplex is supported by default
1405 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1407 status = iface->bind(call, iface, if_version);
1408 call->context = NULL;
1409 if (!NT_STATUS_IS_OK(status)) {
1410 /* we don't want to trigger the iface->unbind() hook */
1411 context->iface = NULL;
1412 talloc_free(context);
1414 * We report this only via ack->result
1416 return NT_STATUS_OK;
1419 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1420 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1421 ack->syntax = context->transfer_syntax;
1422 return NT_STATUS_OK;
1425 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1426 const struct dcerpc_bind *b,
1427 struct dcerpc_ack_ctx *ack_ctx_list)
1431 bool validate_only = false;
1432 bool preferred_ndr32;
1435 * Try to negotiate one new presentation context,
1436 * using our preferred transfer syntax.
1438 for (i = 0; i < b->num_contexts; i++) {
1439 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1440 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1442 status = dcesrv_check_or_create_context(call, b, c, a,
1444 call->conn->preferred_transfer);
1445 if (!NT_STATUS_IS_OK(status)) {
1449 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1451 * We managed to negotiate one context.
1455 validate_only = true;
1459 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1460 call->conn->preferred_transfer);
1461 if (preferred_ndr32) {
1465 return NT_STATUS_OK;
1469 * Try to negotiate one new presentation context,
1470 * using NDR 32 as fallback.
1472 for (i = 0; i < b->num_contexts; i++) {
1473 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1474 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1476 status = dcesrv_check_or_create_context(call, b, c, a,
1478 &ndr_transfer_syntax_ndr);
1479 if (!NT_STATUS_IS_OK(status)) {
1483 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1485 * We managed to negotiate one context.
1489 validate_only = true;
1493 return NT_STATUS_OK;
1496 static void dcesrv_alter_done(struct tevent_req *subreq);
1499 handle a alter context request
1501 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1503 struct dcesrv_connection *conn = call->conn;
1505 bool auth_ok = false;
1506 struct ncacn_packet *pkt = &call->ack_pkt;
1507 uint32_t extra_flags = 0;
1508 struct dcesrv_auth *auth = &call->conn->auth_state;
1509 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1510 struct tevent_req *subreq = NULL;
1513 if (!call->conn->allow_alter) {
1514 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1517 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1519 call->pkt.u.alter.auth_info.length,
1520 0, /* required flags */
1521 DCERPC_PFC_FLAG_FIRST |
1522 DCERPC_PFC_FLAG_LAST |
1523 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1524 0x08 | /* this is not defined, but should be ignored */
1525 DCERPC_PFC_FLAG_CONC_MPX |
1526 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1527 DCERPC_PFC_FLAG_MAYBE |
1528 DCERPC_PFC_FLAG_OBJECT_UUID);
1529 if (!NT_STATUS_IS_OK(status)) {
1530 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1533 auth_ok = dcesrv_auth_alter(call);
1535 if (call->fault_code != 0) {
1536 return dcesrv_fault_disconnect(call, call->fault_code);
1540 if (call->pkt.u.alter.num_contexts < 1) {
1541 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1544 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1545 call->pkt.u.alter.num_contexts);
1546 if (ack_ctx_list == NULL) {
1547 return NT_STATUS_NO_MEMORY;
1551 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1552 * dcesrv_check_or_create_context()) and do some protocol validation
1553 * and set sane defaults.
1555 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1556 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1557 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1559 if (c->num_transfer_syntaxes == 0) {
1560 return dcesrv_fault_disconnect(call,
1561 DCERPC_NCA_S_PROTO_ERROR);
1564 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1565 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1569 * Try to negotiate one new presentation context.
1571 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1572 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1573 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1575 if (!NT_STATUS_IS_OK(status)) {
1579 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1580 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1581 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1582 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1585 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1586 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1589 /* handle any authentication that is being requested */
1591 if (call->in_auth_info.auth_type !=
1592 call->conn->auth_state.auth_type)
1594 return dcesrv_fault_disconnect(call,
1595 DCERPC_FAULT_SEC_PKG_ERROR);
1597 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1600 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1601 pkt->auth_length = 0;
1602 pkt->call_id = call->pkt.call_id;
1603 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1604 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1605 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1606 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1607 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1608 pkt->u.alter_resp.secondary_address = "";
1609 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1610 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1611 pkt->u.alter_resp.auth_info = data_blob_null;
1613 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1618 if (auth->auth_finished) {
1619 return dcesrv_auth_reply(call);
1622 subreq = gensec_update_send(call, call->event_ctx,
1623 auth->gensec_security,
1624 call->in_auth_info.credentials);
1625 if (subreq == NULL) {
1626 return NT_STATUS_NO_MEMORY;
1628 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1630 return dcesrv_conn_auth_wait_setup(conn);
1633 static void dcesrv_alter_done(struct tevent_req *subreq)
1635 struct dcesrv_call_state *call =
1636 tevent_req_callback_data(subreq,
1637 struct dcesrv_call_state);
1638 struct dcesrv_connection *conn = call->conn;
1641 status = gensec_update_recv(subreq, call,
1642 &call->out_auth_info->credentials);
1643 TALLOC_FREE(subreq);
1645 status = dcesrv_auth_complete(call, status);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1648 dcesrv_conn_auth_wait_finished(conn, status);
1652 status = dcesrv_auth_reply(call);
1653 dcesrv_conn_auth_wait_finished(conn, status);
1658 possibly save the call for inspection with ndrdump
1660 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1664 const char *dump_dir;
1665 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1669 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1671 call->context->iface->name,
1672 call->pkt.u.request.opnum,
1674 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1675 DEBUG(0,("RPC SAVED %s\n", fname));
1681 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1683 TALLOC_CTX *frame = talloc_stackframe();
1684 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1685 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1686 const struct dcerpc_sec_vt_pcontext pcontext = {
1687 .abstract_syntax = call->context->iface->syntax_id,
1688 .transfer_syntax = call->context->transfer_syntax,
1690 const struct dcerpc_sec_vt_header2 header2 =
1691 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1692 enum ndr_err_code ndr_err;
1693 struct dcerpc_sec_verification_trailer *vt = NULL;
1694 NTSTATUS status = NT_STATUS_OK;
1697 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1699 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1701 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1702 status = ndr_map_error2ntstatus(ndr_err);
1706 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1707 &pcontext, &header2);
1709 status = NT_STATUS_ACCESS_DENIED;
1718 handle a dcerpc request packet
1720 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1722 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1723 enum dcerpc_transport_t transport =
1724 dcerpc_binding_get_transport(endpoint->ep_description);
1725 struct ndr_pull *pull;
1728 if (!call->conn->allow_request) {
1729 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1732 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1733 if (call->conn->auth_state.gensec_security &&
1734 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1735 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1738 if (call->context == NULL) {
1739 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1740 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1743 switch (call->conn->auth_state.auth_level) {
1744 case DCERPC_AUTH_LEVEL_NONE:
1745 case DCERPC_AUTH_LEVEL_PACKET:
1746 case DCERPC_AUTH_LEVEL_INTEGRITY:
1747 case DCERPC_AUTH_LEVEL_PRIVACY:
1750 if (!call->context->allow_connect) {
1753 addr = tsocket_address_string(call->conn->remote_address,
1756 DEBUG(2, ("%s: restrict auth_level_connect access "
1757 "to [%s] with auth[type=0x%x,level=0x%x] "
1758 "on [%s] from [%s]\n",
1759 __func__, call->context->iface->name,
1760 call->conn->auth_state.auth_type,
1761 call->conn->auth_state.auth_level,
1762 derpc_transport_string_by_transport(transport),
1764 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1769 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1772 addr = tsocket_address_string(call->conn->remote_address, call);
1774 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1775 "to [%s] with auth[type=0x%x,level=0x%x] "
1776 "on [%s] from [%s]\n",
1778 call->context->min_auth_level,
1779 call->context->iface->name,
1780 call->conn->auth_state.auth_type,
1781 call->conn->auth_state.auth_level,
1782 derpc_transport_string_by_transport(transport),
1784 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1787 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1788 NT_STATUS_HAVE_NO_MEMORY(pull);
1790 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1792 call->ndr_pull = pull;
1794 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1795 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1798 status = dcesrv_check_verification_trailer(call);
1799 if (!NT_STATUS_IS_OK(status)) {
1800 uint32_t faultcode = DCERPC_FAULT_OTHER;
1801 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1802 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1804 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1805 nt_errstr(status)));
1806 return dcesrv_fault(call, faultcode);
1809 /* unravel the NDR for the packet */
1810 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1811 if (!NT_STATUS_IS_OK(status)) {
1812 uint8_t extra_flags = 0;
1813 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1814 /* we got an unknown call */
1815 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1816 call->pkt.u.request.opnum,
1817 call->context->iface->name));
1818 dcesrv_save_call(call, "unknown");
1819 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1821 dcesrv_save_call(call, "pullfail");
1823 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1826 if (pull->offset != pull->data_size) {
1827 dcesrv_save_call(call, "extrabytes");
1828 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1829 pull->data_size - pull->offset));
1832 /* call the dispatch function */
1833 status = call->context->iface->dispatch(call, call, call->r);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1836 call->context->iface->name,
1837 call->pkt.u.request.opnum,
1838 dcerpc_errstr(pull, call->fault_code)));
1839 return dcesrv_fault(call, call->fault_code);
1842 /* add the call to the pending list */
1843 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1845 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1846 return NT_STATUS_OK;
1849 return dcesrv_reply(call);
1854 remove the call from the right list when freed
1856 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1858 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1862 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1864 return conn->local_address;
1867 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1869 return conn->remote_address;
1873 process some input to a dcerpc endpoint server.
1875 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1876 struct ncacn_packet *pkt,
1880 struct dcesrv_call_state *call;
1881 struct dcesrv_call_state *existing = NULL;
1883 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1885 data_blob_free(&blob);
1887 return NT_STATUS_NO_MEMORY;
1889 call->conn = dce_conn;
1890 call->event_ctx = dce_conn->event_ctx;
1891 call->msg_ctx = dce_conn->msg_ctx;
1892 call->state_flags = call->conn->state_flags;
1893 call->time = timeval_current();
1894 call->list = DCESRV_LIST_NONE;
1896 talloc_steal(call, pkt);
1897 talloc_steal(call, blob.data);
1900 talloc_set_destructor(call, dcesrv_call_dequeue);
1902 if (call->conn->allow_bind) {
1904 * Only one bind is possible per connection
1906 call->conn->allow_bind = false;
1907 return dcesrv_bind(call);
1910 /* we have to check the signing here, before combining the
1912 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1913 if (!call->conn->allow_request) {
1914 return dcesrv_fault_disconnect(call,
1915 DCERPC_NCA_S_PROTO_ERROR);
1918 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1920 call->pkt.u.request.stub_and_verifier.length,
1921 0, /* required_flags */
1922 DCERPC_PFC_FLAG_FIRST |
1923 DCERPC_PFC_FLAG_LAST |
1924 DCERPC_PFC_FLAG_PENDING_CANCEL |
1925 0x08 | /* this is not defined, but should be ignored */
1926 DCERPC_PFC_FLAG_CONC_MPX |
1927 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1928 DCERPC_PFC_FLAG_MAYBE |
1929 DCERPC_PFC_FLAG_OBJECT_UUID);
1930 if (!NT_STATUS_IS_OK(status)) {
1931 return dcesrv_fault_disconnect(call,
1932 DCERPC_NCA_S_PROTO_ERROR);
1935 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1937 * We don't use dcesrv_fault_disconnect()
1938 * here, because we don't want to set
1939 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1941 * Note that we don't check against the negotiated
1942 * max_recv_frag, but a hard coded value.
1944 dcesrv_call_disconnect_after(call,
1945 "dcesrv_auth_request - frag_length too large");
1946 return dcesrv_fault(call,
1947 DCERPC_NCA_S_PROTO_ERROR);
1950 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1951 if (dce_conn->pending_call_list != NULL) {
1953 * concurrent requests are only allowed
1954 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1956 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1957 dcesrv_call_disconnect_after(call,
1958 "dcesrv_auth_request - "
1959 "existing pending call without CONN_MPX");
1960 return dcesrv_fault(call,
1961 DCERPC_NCA_S_PROTO_ERROR);
1964 /* only one request is possible in the fragmented list */
1965 if (dce_conn->incoming_fragmented_call_list != NULL) {
1966 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1968 * Without DCERPC_PFC_FLAG_CONC_MPX
1969 * we need to return the FAULT on the
1970 * already existing call.
1972 * This is important to get the
1973 * call_id and context_id right.
1976 call = dce_conn->incoming_fragmented_call_list;
1978 dcesrv_call_disconnect_after(call,
1979 "dcesrv_auth_request - "
1980 "existing fragmented call");
1981 return dcesrv_fault(call,
1982 DCERPC_NCA_S_PROTO_ERROR);
1984 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1985 return dcesrv_fault_disconnect(call,
1986 DCERPC_FAULT_NO_CALL_ACTIVE);
1988 call->context = dcesrv_find_context(call->conn,
1989 call->pkt.u.request.context_id);
1990 if (call->context == NULL) {
1991 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1992 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1995 const struct dcerpc_request *nr = &call->pkt.u.request;
1996 const struct dcerpc_request *er = NULL;
1999 existing = dcesrv_find_fragmented_call(dce_conn,
2001 if (existing == NULL) {
2002 dcesrv_call_disconnect_after(call,
2003 "dcesrv_auth_request - "
2004 "no existing fragmented call");
2005 return dcesrv_fault(call,
2006 DCERPC_NCA_S_PROTO_ERROR);
2008 er = &existing->pkt.u.request;
2010 if (call->pkt.ptype != existing->pkt.ptype) {
2011 /* trying to play silly buggers are we? */
2012 return dcesrv_fault_disconnect(existing,
2013 DCERPC_NCA_S_PROTO_ERROR);
2015 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2018 return dcesrv_fault_disconnect(existing,
2019 DCERPC_NCA_S_PROTO_ERROR);
2021 if (nr->context_id != er->context_id) {
2022 return dcesrv_fault_disconnect(existing,
2023 DCERPC_NCA_S_PROTO_ERROR);
2025 if (nr->opnum != er->opnum) {
2026 return dcesrv_fault_disconnect(existing,
2027 DCERPC_NCA_S_PROTO_ERROR);
2032 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2034 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2036 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2037 payload_offset += 16;
2040 ok = dcesrv_auth_pkt_pull(call, &blob,
2041 0, /* required_flags */
2042 DCERPC_PFC_FLAG_FIRST |
2043 DCERPC_PFC_FLAG_LAST |
2044 DCERPC_PFC_FLAG_PENDING_CANCEL |
2045 0x08 | /* this is not defined, but should be ignored */
2046 DCERPC_PFC_FLAG_CONC_MPX |
2047 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2048 DCERPC_PFC_FLAG_MAYBE |
2049 DCERPC_PFC_FLAG_OBJECT_UUID,
2051 &call->pkt.u.request.stub_and_verifier);
2054 * We don't use dcesrv_fault_disconnect()
2055 * here, because we don't want to set
2056 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2058 dcesrv_call_disconnect_after(call,
2059 "dcesrv_auth_request - failed");
2060 if (call->fault_code == 0) {
2061 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2063 return dcesrv_fault(call, call->fault_code);
2067 /* see if this is a continued packet */
2068 if (existing != NULL) {
2069 struct dcerpc_request *er = &existing->pkt.u.request;
2070 const struct dcerpc_request *nr = &call->pkt.u.request;
2076 * Up to 4 MByte are allowed by all fragments
2078 available = dce_conn->max_total_request_size;
2079 if (er->stub_and_verifier.length > available) {
2080 dcesrv_call_disconnect_after(existing,
2081 "dcesrv_auth_request - existing payload too large");
2082 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2084 available -= er->stub_and_verifier.length;
2085 if (nr->alloc_hint > available) {
2086 dcesrv_call_disconnect_after(existing,
2087 "dcesrv_auth_request - alloc hint too large");
2088 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2090 if (nr->stub_and_verifier.length > available) {
2091 dcesrv_call_disconnect_after(existing,
2092 "dcesrv_auth_request - new payload too large");
2093 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2095 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2096 /* allocate at least 1 byte */
2097 alloc_hint = MAX(alloc_hint, 1);
2098 alloc_size = er->stub_and_verifier.length +
2099 nr->stub_and_verifier.length;
2100 alloc_size = MAX(alloc_size, alloc_hint);
2102 er->stub_and_verifier.data =
2103 talloc_realloc(existing,
2104 er->stub_and_verifier.data,
2105 uint8_t, alloc_size);
2106 if (er->stub_and_verifier.data == NULL) {
2108 return dcesrv_fault_with_flags(existing,
2109 DCERPC_FAULT_OUT_OF_RESOURCES,
2110 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2112 memcpy(er->stub_and_verifier.data +
2113 er->stub_and_verifier.length,
2114 nr->stub_and_verifier.data,
2115 nr->stub_and_verifier.length);
2116 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2118 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2124 /* this may not be the last pdu in the chain - if its isn't then
2125 just put it on the incoming_fragmented_call_list and wait for the rest */
2126 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2127 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2129 * Up to 4 MByte are allowed by all fragments
2131 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2132 dcesrv_call_disconnect_after(call,
2133 "dcesrv_auth_request - initial alloc hint too large");
2134 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2136 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2137 return NT_STATUS_OK;
2140 /* This removes any fragments we may have had stashed away */
2141 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2143 switch (call->pkt.ptype) {
2144 case DCERPC_PKT_BIND:
2145 status = dcesrv_bind_nak(call,
2146 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2148 case DCERPC_PKT_AUTH3:
2149 status = dcesrv_auth3(call);
2151 case DCERPC_PKT_ALTER:
2152 status = dcesrv_alter(call);
2154 case DCERPC_PKT_REQUEST:
2155 status = dcesrv_request(call);
2157 case DCERPC_PKT_CO_CANCEL:
2158 case DCERPC_PKT_ORPHANED:
2160 * Window just ignores CO_CANCEL and ORPHANED,
2163 status = NT_STATUS_OK;
2166 case DCERPC_PKT_BIND_ACK:
2167 case DCERPC_PKT_BIND_NAK:
2168 case DCERPC_PKT_ALTER_RESP:
2169 case DCERPC_PKT_RESPONSE:
2170 case DCERPC_PKT_FAULT:
2171 case DCERPC_PKT_SHUTDOWN:
2173 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2177 /* if we are going to be sending a reply then add
2178 it to the list of pending calls. We add it to the end to keep the call
2179 list in the order we will answer */
2180 if (!NT_STATUS_IS_OK(status)) {
2187 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2188 struct loadparm_context *lp_ctx,
2189 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2192 struct dcesrv_context *dce_ctx;
2195 if (!endpoint_servers) {
2196 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2197 return NT_STATUS_INTERNAL_ERROR;
2200 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2201 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2203 if (uid_wrapper_enabled()) {
2204 setenv("UID_WRAPPER_MYUID", "1", 1);
2206 dce_ctx->initial_euid = geteuid();
2207 if (uid_wrapper_enabled()) {
2208 unsetenv("UID_WRAPPER_MYUID");
2211 dce_ctx->endpoint_list = NULL;
2212 dce_ctx->lp_ctx = lp_ctx;
2213 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2214 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2215 dce_ctx->broken_connections = NULL;
2217 for (i=0;endpoint_servers[i];i++) {
2218 const struct dcesrv_endpoint_server *ep_server;
2220 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2222 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2223 return NT_STATUS_INTERNAL_ERROR;
2226 status = ep_server->init_server(dce_ctx, ep_server);
2227 if (!NT_STATUS_IS_OK(status)) {
2228 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2229 nt_errstr(status)));
2234 *_dce_ctx = dce_ctx;
2235 return NT_STATUS_OK;
2238 /* the list of currently registered DCERPC endpoint servers.
2240 static struct ep_server {
2241 struct dcesrv_endpoint_server *ep_server;
2242 } *ep_servers = NULL;
2243 static int num_ep_servers;
2246 register a DCERPC endpoint server.
2248 The 'name' can be later used by other backends to find the operations
2249 structure for this backend.
2252 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2255 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2256 /* its already registered! */
2257 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2259 return NT_STATUS_OBJECT_NAME_COLLISION;
2262 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2264 smb_panic("out of memory in dcerpc_register");
2267 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2268 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2272 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2275 return NT_STATUS_OK;
2279 return the operations structure for a named backend of the specified type
2281 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2285 for (i=0;i<num_ep_servers;i++) {
2286 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2287 return ep_servers[i].ep_server;
2294 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2296 static bool initialized;
2297 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2298 STATIC_dcerpc_server_MODULES_PROTO;
2299 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2300 init_module_fn *shared_init;
2307 shared_init = load_samba_modules(NULL, "dcerpc_server");
2309 run_init_functions(NULL, static_init);
2310 run_init_functions(NULL, shared_init);
2312 talloc_free(shared_init);
2316 return the DCERPC module version, and the size of some critical types
2317 This can be used by endpoint server modules to either detect compilation errors, or provide
2318 multiple implementations for different smbd compilation options in one module
2320 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2322 static const struct dcesrv_critical_sizes critical_sizes = {
2323 DCERPC_MODULE_VERSION,
2324 sizeof(struct dcesrv_context),
2325 sizeof(struct dcesrv_endpoint),
2326 sizeof(struct dcesrv_endpoint_server),
2327 sizeof(struct dcesrv_interface),
2328 sizeof(struct dcesrv_if_list),
2329 sizeof(struct dcesrv_connection),
2330 sizeof(struct dcesrv_call_state),
2331 sizeof(struct dcesrv_auth),
2332 sizeof(struct dcesrv_handle)
2335 return &critical_sizes;
2338 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2340 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2341 struct stream_connection *srv_conn;
2342 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2343 struct stream_connection);
2345 dce_conn->wait_send = NULL;
2346 dce_conn->wait_recv = NULL;
2347 dce_conn->wait_private = NULL;
2349 dce_conn->allow_bind = false;
2350 dce_conn->allow_auth3 = false;
2351 dce_conn->allow_alter = false;
2352 dce_conn->allow_request = false;
2354 if (dce_conn->pending_call_list == NULL) {
2355 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2357 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2358 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2362 if (dce_conn->terminate != NULL) {
2366 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2368 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2369 if (dce_conn->terminate == NULL) {
2370 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2372 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2375 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2377 struct dcesrv_connection *cur, *next;
2379 next = dce_ctx->broken_connections;
2380 while (next != NULL) {
2384 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2385 struct dcesrv_connection_context *context_cur, *context_next;
2387 context_next = cur->contexts;
2388 while (context_next != NULL) {
2389 context_cur = context_next;
2390 context_next = context_cur->next;
2392 dcesrv_connection_context_destructor(context_cur);
2396 dcesrv_terminate_connection(cur, cur->terminate);
2400 /* We need this include to be able to compile on some plateforms
2401 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2403 * It has to be that deep because otherwise we have a conflict on
2404 * const struct dcesrv_interface declaration.
2405 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2406 * which conflict with the bind used before.
2408 #include "system/network.h"
2410 struct dcesrv_sock_reply_state {
2411 struct dcesrv_connection *dce_conn;
2412 struct dcesrv_call_state *call;
2416 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2417 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2419 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2421 struct dcesrv_call_state *call;
2423 call = dce_conn->call_list;
2424 if (!call || !call->replies) {
2428 while (call->replies) {
2429 struct data_blob_list_item *rep = call->replies;
2430 struct dcesrv_sock_reply_state *substate;
2431 struct tevent_req *subreq;
2433 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2435 dcesrv_terminate_connection(dce_conn, "no memory");
2439 substate->dce_conn = dce_conn;
2440 substate->call = NULL;
2442 DLIST_REMOVE(call->replies, rep);
2444 if (call->replies == NULL && call->terminate_reason == NULL) {
2445 substate->call = call;
2448 substate->iov.iov_base = (void *) rep->blob.data;
2449 substate->iov.iov_len = rep->blob.length;
2451 subreq = tstream_writev_queue_send(substate,
2452 dce_conn->event_ctx,
2454 dce_conn->send_queue,
2457 dcesrv_terminate_connection(dce_conn, "no memory");
2460 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2464 if (call->terminate_reason != NULL) {
2465 struct tevent_req *subreq;
2467 subreq = tevent_queue_wait_send(call,
2468 dce_conn->event_ctx,
2469 dce_conn->send_queue);
2471 dcesrv_terminate_connection(dce_conn, __location__);
2474 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2478 DLIST_REMOVE(call->conn->call_list, call);
2479 call->list = DCESRV_LIST_NONE;
2482 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2484 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2485 struct dcesrv_sock_reply_state);
2489 struct dcesrv_call_state *call = substate->call;
2491 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2492 TALLOC_FREE(subreq);
2494 status = map_nt_error_from_unix_common(sys_errno);
2495 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2499 talloc_free(substate);
2505 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2507 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2509 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2510 struct dcesrv_call_state);
2514 /* make sure we stop send queue before removing subreq */
2515 tevent_queue_stop(call->conn->send_queue);
2517 ok = tevent_queue_wait_recv(subreq);
2518 TALLOC_FREE(subreq);
2520 dcesrv_terminate_connection(call->conn, __location__);
2524 /* disconnect after 200 usecs */
2525 tv = timeval_current_ofs_usec(200);
2526 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2527 if (subreq == NULL) {
2528 dcesrv_terminate_connection(call->conn, __location__);
2531 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2535 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2537 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2538 struct dcesrv_call_state);
2541 ok = tevent_wakeup_recv(subreq);
2542 TALLOC_FREE(subreq);
2544 dcesrv_terminate_connection(call->conn, __location__);
2548 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2551 struct dcesrv_socket_context {
2552 const struct dcesrv_endpoint *endpoint;
2553 struct dcesrv_context *dcesrv_ctx;
2557 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2559 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2562 struct dcesrv_socket_context *dcesrv_sock =
2563 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2564 enum dcerpc_transport_t transport =
2565 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2566 struct dcesrv_connection *dcesrv_conn = NULL;
2568 struct tevent_req *subreq;
2569 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2571 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2573 if (!srv_conn->session_info) {
2574 status = auth_anonymous_session_info(srv_conn,
2576 &srv_conn->session_info);
2577 if (!NT_STATUS_IS_OK(status)) {
2578 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2579 nt_errstr(status)));
2580 stream_terminate_connection(srv_conn, nt_errstr(status));
2586 * This fills in dcesrv_conn->endpoint with the endpoint
2587 * associated with the socket. From this point on we know
2588 * which (group of) services we are handling, but not the
2589 * specific interface.
2592 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2594 dcesrv_sock->endpoint,
2595 srv_conn->session_info,
2596 srv_conn->event.ctx,
2598 srv_conn->server_id,
2599 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2601 if (!NT_STATUS_IS_OK(status)) {
2602 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2603 nt_errstr(status)));
2604 stream_terminate_connection(srv_conn, nt_errstr(status));
2608 dcesrv_conn->transport.private_data = srv_conn;
2609 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2611 TALLOC_FREE(srv_conn->event.fde);
2613 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2614 if (!dcesrv_conn->send_queue) {
2615 status = NT_STATUS_NO_MEMORY;
2616 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2617 nt_errstr(status)));
2618 stream_terminate_connection(srv_conn, nt_errstr(status));
2622 if (transport == NCACN_NP) {
2623 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2624 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2625 &srv_conn->tstream);
2627 ret = tstream_bsd_existing_socket(dcesrv_conn,
2628 socket_get_fd(srv_conn->socket),
2629 &dcesrv_conn->stream);
2631 status = map_nt_error_from_unix_common(errno);
2632 DEBUG(0, ("dcesrv_sock_accept: "
2633 "failed to setup tstream: %s\n",
2634 nt_errstr(status)));
2635 stream_terminate_connection(srv_conn, nt_errstr(status));
2638 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2641 dcesrv_conn->local_address = srv_conn->local_address;
2642 dcesrv_conn->remote_address = srv_conn->remote_address;
2644 if (transport == NCALRPC) {
2649 sock_fd = socket_get_fd(srv_conn->socket);
2650 if (sock_fd == -1) {
2651 stream_terminate_connection(
2652 srv_conn, "socket_get_fd failed\n");
2656 ret = getpeereid(sock_fd, &uid, &gid);
2658 status = map_nt_error_from_unix_common(errno);
2659 DEBUG(0, ("dcesrv_sock_accept: "
2660 "getpeereid() failed for NCALRPC: %s\n",
2661 nt_errstr(status)));
2662 stream_terminate_connection(srv_conn, nt_errstr(status));
2665 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2666 struct tsocket_address *r = NULL;
2668 ret = tsocket_address_unix_from_path(dcesrv_conn,
2669 "/root/ncalrpc_as_system",
2672 status = map_nt_error_from_unix_common(errno);
2673 DEBUG(0, ("dcesrv_sock_accept: "
2674 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2675 nt_errstr(status)));
2676 stream_terminate_connection(srv_conn, nt_errstr(status));
2679 dcesrv_conn->remote_address = r;
2683 srv_conn->private_data = dcesrv_conn;
2685 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2687 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2688 dcesrv_conn->event_ctx,
2689 dcesrv_conn->stream);
2691 status = NT_STATUS_NO_MEMORY;
2692 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2693 nt_errstr(status)));
2694 stream_terminate_connection(srv_conn, nt_errstr(status));
2697 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2702 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2704 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2706 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2707 struct dcesrv_connection);
2708 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2709 struct ncacn_packet *pkt;
2713 if (dce_conn->terminate) {
2715 * if the current connection is broken
2716 * we need to clean it up before any other connection
2718 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2719 dcesrv_cleanup_broken_connections(dce_ctx);
2723 dcesrv_cleanup_broken_connections(dce_ctx);
2725 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2727 TALLOC_FREE(subreq);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2733 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2740 * This is used to block the connection during
2741 * pending authentication.
2743 if (dce_conn->wait_send != NULL) {
2744 subreq = dce_conn->wait_send(dce_conn,
2745 dce_conn->event_ctx,
2746 dce_conn->wait_private);
2748 status = NT_STATUS_NO_MEMORY;
2749 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2752 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2756 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2757 dce_conn->event_ctx,
2760 status = NT_STATUS_NO_MEMORY;
2761 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2764 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2767 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2769 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2770 struct dcesrv_connection);
2771 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2774 if (dce_conn->terminate) {
2776 * if the current connection is broken
2777 * we need to clean it up before any other connection
2779 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2780 dcesrv_cleanup_broken_connections(dce_ctx);
2784 dcesrv_cleanup_broken_connections(dce_ctx);
2786 status = dce_conn->wait_recv(subreq);
2787 dce_conn->wait_send = NULL;
2788 dce_conn->wait_recv = NULL;
2789 dce_conn->wait_private = NULL;
2790 TALLOC_FREE(subreq);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2796 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2797 dce_conn->event_ctx,
2800 status = NT_STATUS_NO_MEMORY;
2801 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2804 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2807 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2809 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2810 struct dcesrv_connection);
2811 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2814 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2816 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2817 struct dcesrv_connection);
2818 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2822 static const struct stream_server_ops dcesrv_stream_ops = {
2824 .accept_connection = dcesrv_sock_accept,
2825 .recv_handler = dcesrv_sock_recv,
2826 .send_handler = dcesrv_sock_send,
2829 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2830 struct loadparm_context *lp_ctx,
2831 struct dcesrv_endpoint *e,
2832 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2834 struct dcesrv_socket_context *dcesrv_sock;
2837 const char *endpoint;
2839 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2840 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2842 /* remember the endpoint of this socket */
2843 dcesrv_sock->endpoint = e;
2844 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2846 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2848 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2849 model_ops, &dcesrv_stream_ops,
2850 "unix", endpoint, &port,
2851 lpcfg_socket_options(lp_ctx),
2853 if (!NT_STATUS_IS_OK(status)) {
2854 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2855 endpoint, nt_errstr(status)));
2861 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2862 struct loadparm_context *lp_ctx,
2863 struct dcesrv_endpoint *e,
2864 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2866 struct dcesrv_socket_context *dcesrv_sock;
2870 const char *endpoint;
2872 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2874 if (endpoint == NULL) {
2876 * No identifier specified: use DEFAULT.
2878 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2879 * no endpoint and let the epmapper worry about it.
2881 endpoint = "DEFAULT";
2882 status = dcerpc_binding_set_string_option(e->ep_description,
2885 if (!NT_STATUS_IS_OK(status)) {
2886 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2887 nt_errstr(status)));
2892 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2895 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2896 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2898 /* remember the endpoint of this socket */
2899 dcesrv_sock->endpoint = e;
2900 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2902 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2903 model_ops, &dcesrv_stream_ops,
2904 "unix", full_path, &port,
2905 lpcfg_socket_options(lp_ctx),
2907 if (!NT_STATUS_IS_OK(status)) {
2908 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2909 endpoint, full_path, nt_errstr(status)));
2914 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2915 struct loadparm_context *lp_ctx,
2916 struct dcesrv_endpoint *e,
2917 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2919 struct dcesrv_socket_context *dcesrv_sock;
2921 const char *endpoint;
2923 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2924 if (endpoint == NULL) {
2925 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2926 return NT_STATUS_INVALID_PARAMETER;
2929 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2930 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2932 /* remember the endpoint of this socket */
2933 dcesrv_sock->endpoint = e;
2934 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2936 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2937 model_ops, &dcesrv_stream_ops,
2940 if (!NT_STATUS_IS_OK(status)) {
2941 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2942 endpoint, nt_errstr(status)));
2946 return NT_STATUS_OK;
2950 add a socket address to the list of events, one event per dcerpc endpoint
2952 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2953 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2954 const char *address)
2956 struct dcesrv_socket_context *dcesrv_sock;
2959 const char *endpoint;
2962 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2963 if (endpoint != NULL) {
2964 port = atoi(endpoint);
2967 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2968 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2970 /* remember the endpoint of this socket */
2971 dcesrv_sock->endpoint = e;
2972 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2974 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2975 model_ops, &dcesrv_stream_ops,
2976 "ip", address, &port,
2977 lpcfg_socket_options(dce_ctx->lp_ctx),
2979 if (!NT_STATUS_IS_OK(status)) {
2980 struct dcesrv_if_list *iface;
2981 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2983 for (iface = e->interface_list; iface; iface = iface->next) {
2984 DEBUGADD(0, ("%s ", iface->iface.name));
2986 DEBUGADD(0, ("failed - %s",
2987 nt_errstr(status)));
2991 snprintf(port_str, sizeof(port_str), "%u", port);
2993 status = dcerpc_binding_set_string_option(e->ep_description,
2994 "endpoint", port_str);
2995 if (!NT_STATUS_IS_OK(status)) {
2996 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2997 port_str, nt_errstr(status)));
3000 struct dcesrv_if_list *iface;
3001 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3002 address, port_str));
3003 for (iface = e->interface_list; iface; iface = iface->next) {
3004 DEBUGADD(4, ("%s ", iface->iface.name));
3006 DEBUGADD(4, ("\n"));
3009 return NT_STATUS_OK;
3012 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3014 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3015 struct loadparm_context *lp_ctx,
3016 struct dcesrv_endpoint *e,
3017 struct tevent_context *event_ctx, const struct model_ops *model_ops)
3021 /* Add TCP/IP sockets */
3022 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3025 struct interface *ifaces;
3027 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3029 num_interfaces = iface_list_count(ifaces);
3030 for(i = 0; i < num_interfaces; i++) {
3031 const char *address = iface_list_n_ip(ifaces, i);
3032 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
3033 NT_STATUS_NOT_OK_RETURN(status);
3039 wcard = iface_list_wildcard(dce_ctx);
3040 NT_STATUS_HAVE_NO_MEMORY(wcard);
3041 for (i=0; wcard[i]; i++) {
3042 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
3043 if (NT_STATUS_IS_OK(status)) {
3048 if (num_binds == 0) {
3049 return NT_STATUS_INVALID_PARAMETER_MIX;
3053 return NT_STATUS_OK;
3056 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3057 struct loadparm_context *lp_ctx,
3058 struct dcesrv_endpoint *e,
3059 struct tevent_context *event_ctx,
3060 const struct model_ops *model_ops)
3062 enum dcerpc_transport_t transport =
3063 dcerpc_binding_get_transport(e->ep_description);
3065 switch (transport) {
3066 case NCACN_UNIX_STREAM:
3067 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3070 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3073 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3076 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3079 return NT_STATUS_NOT_SUPPORTED;
3085 * retrieve credentials from a dce_call
3087 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3089 return dce_call->conn->auth_state.session_info->credentials;
3093 * returns true if this is an authenticated call
3095 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3097 enum security_user_level level;
3098 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3099 return level >= SECURITY_USER;
3103 * retrieve account_name for a dce_call
3105 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3107 return dce_call->context->conn->auth_state.session_info->info->account_name;