2 Unix SMB/CIFS implementation.
4 server side dcerpc core code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44 #include "../lib/util/tevent_ntstatus.h"
46 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
47 const struct dcerpc_bind *b,
48 struct dcerpc_ack_ctx *ack_ctx_list);
51 find an association group given a assoc_group_id
53 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
58 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
62 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
66 take a reference to an existing association group
68 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
69 struct dcesrv_context *dce_ctx,
72 struct dcesrv_assoc_group *assoc_group;
74 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
75 if (assoc_group == NULL) {
76 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
79 return talloc_reference(mem_ctx, assoc_group);
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
85 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
87 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
94 allocate a new association group
96 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
97 struct dcesrv_context *dce_ctx)
99 struct dcesrv_assoc_group *assoc_group;
102 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103 if (assoc_group == NULL) {
107 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
109 talloc_free(assoc_group);
110 DEBUG(0,(__location__ ": Out of association groups!\n"));
114 assoc_group->id = id;
115 assoc_group->dce_ctx = dce_ctx;
117 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
124 see if two endpoints match
126 static bool endpoints_match(const struct dcerpc_binding *ep1,
127 const struct dcerpc_binding *ep2)
129 enum dcerpc_transport_t t1;
130 enum dcerpc_transport_t t2;
134 t1 = dcerpc_binding_get_transport(ep1);
135 t2 = dcerpc_binding_get_transport(ep2);
137 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
138 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
148 if (strcasecmp(e1, e2) != 0) {
156 find an endpoint in the dcesrv_context
158 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
159 const struct dcerpc_binding *ep_description)
161 struct dcesrv_endpoint *ep;
162 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
163 if (endpoints_match(ep->ep_description, ep_description)) {
171 find a registered context_id from a bind or alter_context
173 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
176 struct dcesrv_connection_context *c;
177 for (c=conn->contexts;c;c=c->next) {
178 if (c->context_id == context_id) return c;
184 see if a uuid and if_version match to an interface
186 static bool interface_match(const struct dcesrv_interface *if1,
187 const struct dcesrv_interface *if2)
189 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
190 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
194 find the interface operations on any endpoint with this binding
196 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
197 struct dcerpc_binding *binding,
198 const struct dcesrv_interface *iface)
200 struct dcesrv_endpoint *ep;
201 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
202 if (endpoints_match(ep->ep_description, binding)) {
203 struct dcesrv_if_list *ifl;
204 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
205 if (interface_match(&(ifl->iface), iface)) {
206 return &(ifl->iface);
215 see if a uuid and if_version match to an interface
217 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
218 const struct GUID *uuid, uint32_t if_version)
220 return (iface->syntax_id.if_version == if_version &&
221 GUID_equal(&iface->syntax_id.uuid, uuid));
225 find the interface operations on an endpoint by uuid
227 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
228 const struct GUID *uuid, uint32_t if_version)
230 struct dcesrv_if_list *ifl;
231 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
232 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
233 return &(ifl->iface);
240 find the earlier parts of a fragmented call awaiting reassembily
242 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
244 struct dcesrv_call_state *c;
245 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
246 if (c->pkt.call_id == call_id) {
254 register an interface on an endpoint
256 An endpoint is one unix domain socket (for ncalrpc), one TCP port
257 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
259 Each endpoint can have many interfaces such as netlogon, lsa or
260 samr. Some have essentially the full set.
262 This is driven from the set of interfaces listed in each IDL file
263 via the PIDL generated *__op_init_server() functions.
265 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
267 const struct dcesrv_interface *iface,
268 const struct security_descriptor *sd)
270 struct dcesrv_endpoint *ep;
271 struct dcesrv_if_list *ifl;
272 struct dcerpc_binding *binding;
275 enum dcerpc_transport_t transport;
276 char *ep_string = NULL;
277 bool use_single_process = true;
278 const char *ep_process_string;
281 * If we are not using handles, there is no need for force
282 * this service into using a single process.
284 * However, due to the way we listen for RPC packets, we can
285 * only do this if we have a single service per pipe or TCP
286 * port, so we still force a single combined process for
289 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
290 use_single_process = false;
293 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
295 if (NT_STATUS_IS_ERR(status)) {
296 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
300 transport = dcerpc_binding_get_transport(binding);
301 if (transport == NCACN_IP_TCP) {
306 * First check if there is already a port specified, eg
307 * for epmapper on ncacn_ip_tcp:[135]
310 = dcerpc_binding_get_string_option(binding,
312 if (endpoint == NULL) {
313 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
314 "rpc server port", iface->name, 0);
317 * For RPC services that are not set to use a single
318 * process, we do not default to using the 'rpc server
319 * port' because that would cause a double-bind on
322 if (port == 0 && !use_single_process) {
323 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
326 snprintf(port_str, sizeof(port_str), "%u", port);
327 status = dcerpc_binding_set_string_option(binding,
330 if (!NT_STATUS_IS_OK(status)) {
337 /* see if the interface is already registered on the endpoint */
338 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
339 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
340 iface->name, ep_name));
341 return NT_STATUS_OBJECT_NAME_COLLISION;
344 /* check if this endpoint exists
346 ep = find_endpoint(dce_ctx, binding);
350 * We want a new port on ncacn_ip_tcp for NETLOGON, so
351 * it can be multi-process. Other processes can also
352 * listen on distinct ports, if they have one forced
353 * in the code above with eg 'rpc server port:drsuapi = 1027'
355 * If we have mulitiple endpoints on port 0, they each
356 * get an epemeral port (currently by walking up from
359 * Because one endpoint can only have one process
360 * model, we add a new IP_TCP endpoint for each model.
362 * This works in conjunction with the forced overwrite
363 * of ep->use_single_process below.
365 if (ep->use_single_process != use_single_process
366 && transport == NCACN_IP_TCP) {
371 if (ep == NULL || add_ep) {
372 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
374 return NT_STATUS_NO_MEMORY;
377 ep->ep_description = talloc_move(ep, &binding);
380 /* add mgmt interface */
381 ifl = talloc_zero(ep, struct dcesrv_if_list);
383 return NT_STATUS_NO_MEMORY;
386 ifl->iface = dcesrv_get_mgmt_interface();
388 DLIST_ADD(ep->interface_list, ifl);
392 * By default don't force into a single process, but if any
393 * interface on this endpoint on this service uses handles
394 * (most do), then we must force into single process mode
396 * By overwriting this each time a new interface is added to
397 * this endpoint, we end up with the most restrictive setting.
399 if (use_single_process) {
400 ep->use_single_process = true;
403 /* talloc a new interface list element */
404 ifl = talloc_zero(ep, struct dcesrv_if_list);
406 return NT_STATUS_NO_MEMORY;
409 /* copy the given interface struct to the one on the endpoints interface list */
410 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
412 /* if we have a security descriptor given,
413 * we should see if we can set it up on the endpoint
416 /* if there's currently no security descriptor given on the endpoint
419 if (ep->sd == NULL) {
420 ep->sd = security_descriptor_copy(ep, sd);
423 /* if now there's no security descriptor given on the endpoint
424 * something goes wrong, either we failed to copy the security descriptor
425 * or there was already one on the endpoint
427 if (ep->sd != NULL) {
428 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
429 " on endpoint '%s'\n",
430 iface->name, ep_name));
431 if (add_ep) free(ep);
433 return NT_STATUS_OBJECT_NAME_COLLISION;
437 /* finally add the interface on the endpoint */
438 DLIST_ADD(ep->interface_list, ifl);
440 /* if it's a new endpoint add it to the dcesrv_context */
442 DLIST_ADD(dce_ctx->endpoint_list, ep);
445 /* Re-get the string as we may have set a port */
446 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
448 if (use_single_process) {
449 ep_process_string = "single process required";
451 ep_process_string = "multi process compatible";
454 DBG_INFO("dcesrv_interface_register: interface '%s' "
455 "registered on endpoint '%s' (%s)\n",
456 iface->name, ep_string, ep_process_string);
457 TALLOC_FREE(ep_string);
462 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
463 DATA_BLOB *session_key)
465 if (auth->session_info == NULL) {
466 return NT_STATUS_NO_USER_SESSION_KEY;
469 if (auth->session_info->session_key.length == 0) {
470 return NT_STATUS_NO_USER_SESSION_KEY;
473 *session_key = auth->session_info->session_key;
477 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
478 DATA_BLOB *session_key)
480 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
481 return NT_STATUS_NO_USER_SESSION_KEY;
484 return dcesrv_session_info_session_key(auth, session_key);
487 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
488 DATA_BLOB *session_key)
490 return dcerpc_generic_session_key(NULL, session_key);
494 * Fetch the authentication session key if available.
496 * This is the key generated by a gensec authentication.
499 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
500 DATA_BLOB *session_key)
502 struct dcesrv_auth *auth = &call->conn->auth_state;
504 return dcesrv_session_info_session_key(auth, session_key);
508 * Fetch the transport session key if available.
509 * Typically this is the SMB session key
510 * or a fixed key for local transports.
512 * The key is always truncated to 16 bytes.
514 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
515 DATA_BLOB *session_key)
517 struct dcesrv_auth *auth = &call->conn->auth_state;
520 if (auth->session_key_fn == NULL) {
521 return NT_STATUS_NO_USER_SESSION_KEY;
524 status = auth->session_key_fn(auth, session_key);
525 if (!NT_STATUS_IS_OK(status)) {
529 session_key->length = MIN(session_key->length, 16);
535 connect to a dcerpc endpoint
537 static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
539 const struct dcesrv_endpoint *ep,
540 struct auth_session_info *session_info,
541 struct tevent_context *event_ctx,
542 struct imessaging_context *msg_ctx,
543 struct server_id server_id,
544 uint32_t state_flags,
545 struct dcesrv_connection **_p)
547 enum dcerpc_transport_t transport =
548 dcerpc_binding_get_transport(ep->ep_description);
549 struct dcesrv_connection *p;
552 return NT_STATUS_ACCESS_DENIED;
555 p = talloc_zero(mem_ctx, struct dcesrv_connection);
556 NT_STATUS_HAVE_NO_MEMORY(p);
558 if (!talloc_reference(p, session_info)) {
560 return NT_STATUS_NO_MEMORY;
563 p->dce_ctx = dce_ctx;
565 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
566 p->event_ctx = event_ctx;
567 p->msg_ctx = msg_ctx;
568 p->server_id = server_id;
569 p->state_flags = state_flags;
570 p->allow_bind = true;
571 p->max_recv_frag = 5840;
572 p->max_xmit_frag = 5840;
573 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
575 p->auth_state.session_info = session_info;
578 p->auth_state.session_key_fn = dcesrv_remote_session_key;
581 case NCACN_UNIX_STREAM:
582 p->auth_state.session_key_fn = dcesrv_local_fixed_session_key;
586 * All other's get a NULL pointer, which
587 * results in NT_STATUS_NO_USER_SESSION_KEY
593 * For now we only support NDR32.
595 p->preferred_transfer = &ndr_transfer_syntax_ndr;
602 move a call from an existing linked list to the specified list. This
603 prevents bugs where we forget to remove the call from a previous
606 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
607 enum dcesrv_call_list list)
609 switch (call->list) {
610 case DCESRV_LIST_NONE:
612 case DCESRV_LIST_CALL_LIST:
613 DLIST_REMOVE(call->conn->call_list, call);
615 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
616 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
618 case DCESRV_LIST_PENDING_CALL_LIST:
619 DLIST_REMOVE(call->conn->pending_call_list, call);
624 case DCESRV_LIST_NONE:
626 case DCESRV_LIST_CALL_LIST:
627 DLIST_ADD_END(call->conn->call_list, call);
629 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
630 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
632 case DCESRV_LIST_PENDING_CALL_LIST:
633 DLIST_ADD_END(call->conn->pending_call_list, call);
638 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
641 if (call->conn->terminate != NULL) {
645 call->conn->allow_bind = false;
646 call->conn->allow_alter = false;
647 call->conn->allow_auth3 = false;
648 call->conn->allow_request = false;
650 call->terminate_reason = talloc_strdup(call, reason);
651 if (call->terminate_reason == NULL) {
652 call->terminate_reason = __location__;
657 return a dcerpc bind_nak
659 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
661 struct ncacn_packet pkt;
662 struct dcerpc_bind_nak_version version;
663 struct data_blob_list_item *rep;
665 static const uint8_t _pad[3] = { 0, };
668 * We add the call to the pending_call_list
669 * in order to defer the termination.
671 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
673 /* setup a bind_nak */
674 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
676 pkt.call_id = call->pkt.call_id;
677 pkt.ptype = DCERPC_PKT_BIND_NAK;
678 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
679 pkt.u.bind_nak.reject_reason = reason;
680 version.rpc_vers = 5;
681 version.rpc_vers_minor = 0;
682 pkt.u.bind_nak.num_versions = 1;
683 pkt.u.bind_nak.versions = &version;
684 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
686 rep = talloc_zero(call, struct data_blob_list_item);
688 return NT_STATUS_NO_MEMORY;
691 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
692 if (!NT_STATUS_IS_OK(status)) {
696 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
698 DLIST_ADD_END(call->replies, rep);
699 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
701 if (call->conn->call_list && call->conn->call_list->replies) {
702 if (call->conn->transport.report_output_data) {
703 call->conn->transport.report_output_data(call->conn);
710 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
714 * We add the call to the pending_call_list
715 * in order to defer the termination.
717 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
719 return dcesrv_fault_with_flags(call, fault_code,
720 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
723 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
725 DLIST_REMOVE(c->conn->contexts, c);
727 if (c->iface && c->iface->unbind) {
728 c->iface->unbind(c, c->iface);
735 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
737 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
738 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
739 enum dcerpc_transport_t transport =
740 dcerpc_binding_get_transport(endpoint->ep_description);
741 struct dcesrv_connection_context *context = dce_call->context;
742 const struct dcesrv_interface *iface = context->iface;
744 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
746 if (transport == NCALRPC) {
747 context->allow_connect = true;
752 * allow overwrite per interface
753 * allow dcerpc auth level connect:<interface>
755 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
756 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
757 "allow dcerpc auth level connect",
759 context->allow_connect);
762 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
763 const struct dcesrv_interface *iface)
765 if (dce_call->context == NULL) {
766 return NT_STATUS_INTERNAL_ERROR;
770 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
771 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
773 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
777 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
778 const struct dcesrv_interface *iface)
780 if (dce_call->context == NULL) {
781 return NT_STATUS_INTERNAL_ERROR;
784 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
788 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
789 const struct dcesrv_interface *iface)
791 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
792 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
793 enum dcerpc_transport_t transport =
794 dcerpc_binding_get_transport(endpoint->ep_description);
795 struct dcesrv_connection_context *context = dce_call->context;
797 if (context == NULL) {
798 return NT_STATUS_INTERNAL_ERROR;
801 if (transport == NCALRPC) {
802 context->allow_connect = true;
807 * allow overwrite per interface
808 * allow dcerpc auth level connect:<interface>
810 context->allow_connect = false;
811 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
812 "allow dcerpc auth level connect",
814 context->allow_connect);
818 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
819 const struct dcesrv_interface *iface)
821 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
822 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
823 enum dcerpc_transport_t transport =
824 dcerpc_binding_get_transport(endpoint->ep_description);
825 struct dcesrv_connection_context *context = dce_call->context;
827 if (context == NULL) {
828 return NT_STATUS_INTERNAL_ERROR;
831 if (transport == NCALRPC) {
832 context->allow_connect = true;
837 * allow overwrite per interface
838 * allow dcerpc auth level connect:<interface>
840 context->allow_connect = true;
841 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
842 "allow dcerpc auth level connect",
844 context->allow_connect);
848 struct dcesrv_conn_auth_wait_context {
849 struct tevent_req *req;
854 struct dcesrv_conn_auth_wait_state {
858 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
859 struct tevent_context *ev,
862 struct dcesrv_conn_auth_wait_context *auth_wait =
863 talloc_get_type_abort(private_data,
864 struct dcesrv_conn_auth_wait_context);
865 struct tevent_req *req = NULL;
866 struct dcesrv_conn_auth_wait_state *state = NULL;
868 req = tevent_req_create(mem_ctx, &state,
869 struct dcesrv_conn_auth_wait_state);
873 auth_wait->req = req;
875 tevent_req_defer_callback(req, ev);
877 if (!auth_wait->done) {
881 if (tevent_req_nterror(req, auth_wait->status)) {
882 return tevent_req_post(req, ev);
885 tevent_req_done(req);
886 return tevent_req_post(req, ev);
889 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
891 return tevent_req_simple_recv_ntstatus(req);
894 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
896 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
898 if (conn->wait_send != NULL) {
899 return NT_STATUS_INTERNAL_ERROR;
902 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
903 if (auth_wait == NULL) {
904 return NT_STATUS_NO_MEMORY;
907 conn->wait_private = auth_wait;
908 conn->wait_send = dcesrv_conn_auth_wait_send;
909 conn->wait_recv = dcesrv_conn_auth_wait_recv;
913 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
916 struct dcesrv_conn_auth_wait_context *auth_wait =
917 talloc_get_type_abort(conn->wait_private,
918 struct dcesrv_conn_auth_wait_context);
920 auth_wait->done = true;
921 auth_wait->status = status;
923 if (auth_wait->req == NULL) {
927 if (tevent_req_nterror(auth_wait->req, status)) {
931 tevent_req_done(auth_wait->req);
934 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
936 static void dcesrv_bind_done(struct tevent_req *subreq);
939 handle a bind request
941 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
943 struct dcesrv_connection *conn = call->conn;
944 struct ncacn_packet *pkt = &call->ack_pkt;
946 uint32_t extra_flags = 0;
947 uint16_t max_req = 0;
948 uint16_t max_rep = 0;
949 const char *ep_prefix = "";
950 const char *endpoint = NULL;
951 struct dcesrv_auth *auth = &call->conn->auth_state;
952 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
953 struct dcerpc_ack_ctx *ack_features = NULL;
954 struct tevent_req *subreq = NULL;
957 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
959 call->pkt.u.bind.auth_info.length,
960 0, /* required flags */
961 DCERPC_PFC_FLAG_FIRST |
962 DCERPC_PFC_FLAG_LAST |
963 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
964 0x08 | /* this is not defined, but should be ignored */
965 DCERPC_PFC_FLAG_CONC_MPX |
966 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
967 DCERPC_PFC_FLAG_MAYBE |
968 DCERPC_PFC_FLAG_OBJECT_UUID);
969 if (!NT_STATUS_IS_OK(status)) {
970 return dcesrv_bind_nak(call,
971 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
974 /* max_recv_frag and max_xmit_frag result always in the same value! */
975 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
976 call->pkt.u.bind.max_recv_frag);
978 * The values are between 2048 and 5840 tested against Windows 2012R2
979 * via ncacn_ip_tcp on port 135.
981 max_req = MAX(2048, max_req);
982 max_rep = MIN(max_req, call->conn->max_recv_frag);
983 /* They are truncated to an 8 byte boundary. */
986 /* max_recv_frag and max_xmit_frag result always in the same value! */
987 call->conn->max_recv_frag = max_rep;
988 call->conn->max_xmit_frag = max_rep;
991 if provided, check the assoc_group is valid
993 if (call->pkt.u.bind.assoc_group_id != 0) {
994 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
996 call->pkt.u.bind.assoc_group_id);
998 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
999 call->conn->dce_ctx);
1003 * The NETLOGON server does not use handles and so
1004 * there is no need to support association groups, but
1005 * we need to give back a number regardless.
1007 * We have to do this when it is not run as a single process,
1008 * because then it can't see the other valid association
1009 * groups. We handle this genericly for all endpoints not
1010 * running in single process mode.
1012 * We know which endpoint we are on even before checking the
1013 * iface UUID, so for simplicity we enforce the same policy
1014 * for all interfaces on the endpoint.
1016 * This means that where NETLOGON
1017 * shares an endpoint (such as ncalrpc or of 'lsa over
1018 * netlogon' is set) we will still check association groups.
1022 if (call->conn->assoc_group == NULL &&
1023 !call->conn->endpoint->use_single_process) {
1024 call->conn->assoc_group
1025 = dcesrv_assoc_group_new(call->conn,
1026 call->conn->dce_ctx);
1028 if (call->conn->assoc_group == NULL) {
1029 return dcesrv_bind_nak(call, 0);
1032 if (call->pkt.u.bind.num_contexts < 1) {
1033 return dcesrv_bind_nak(call, 0);
1036 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1037 call->pkt.u.bind.num_contexts);
1038 if (ack_ctx_list == NULL) {
1039 return dcesrv_bind_nak(call, 0);
1043 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1044 * dcesrv_check_or_create_context()) and do some protocol validation
1045 * and set sane defaults.
1047 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1048 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1049 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1050 bool is_feature = false;
1051 uint64_t features = 0;
1053 if (c->num_transfer_syntaxes == 0) {
1054 return dcesrv_bind_nak(call, 0);
1057 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1058 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1061 * It's only treated as bind time feature request, if the first
1062 * transfer_syntax matches, all others are ignored.
1064 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1070 if (ack_features != NULL) {
1072 * Only one bind time feature context is allowed.
1074 return dcesrv_bind_nak(call, 0);
1078 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1079 a->reason.negotiate = 0;
1080 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1081 /* not supported yet */
1083 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1084 a->reason.negotiate |=
1085 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1088 call->conn->bind_time_features = a->reason.negotiate;
1092 * Try to negotiate one new presentation context.
1094 * Deep in here we locate the iface (by uuid) that the client
1095 * requested, from the list of interfaces on the
1096 * call->conn->endpoint, and call iface->bind() on that iface.
1098 * call->conn was set up at the accept() of the socket, and
1099 * call->conn->endpoint has a list of interfaces restricted to
1100 * this port or pipe.
1102 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1103 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1104 return dcesrv_bind_nak(call, 0);
1106 if (!NT_STATUS_IS_OK(status)) {
1111 * At this point we still don't know which interface (eg
1112 * netlogon, lsa, drsuapi) the caller requested in this bind!
1113 * The most recently added context is available as the first
1114 * element in the linked list at call->conn->contexts, that is
1115 * call->conn->contexts->iface, but they may not have
1116 * requested one at all!
1119 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1120 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1121 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1122 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1125 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1126 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1130 * After finding the interface and setting up the NDR
1131 * transport negotiation etc, handle any authentication that
1132 * is being requested.
1134 if (!dcesrv_auth_bind(call)) {
1136 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1138 * With DCERPC_AUTH_LEVEL_NONE, we get the
1139 * reject_reason in auth->auth_context_id.
1141 return dcesrv_bind_nak(call, auth->auth_context_id);
1145 * This must a be a temporary failure e.g. talloc or invalid
1146 * configuration, e.g. no machine account.
1148 return dcesrv_bind_nak(call,
1149 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1152 /* setup a bind_ack */
1153 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1154 pkt->auth_length = 0;
1155 pkt->call_id = call->pkt.call_id;
1156 pkt->ptype = DCERPC_PKT_BIND_ACK;
1157 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1158 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1159 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1160 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1162 endpoint = dcerpc_binding_get_string_option(
1163 call->conn->endpoint->ep_description,
1165 if (endpoint == NULL) {
1169 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1171 * TODO: check if this is really needed
1173 * Or if we should fix this in our idl files.
1175 ep_prefix = "\\PIPE\\";
1179 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1182 if (pkt->u.bind_ack.secondary_address == NULL) {
1183 return NT_STATUS_NO_MEMORY;
1185 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1186 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1187 pkt->u.bind_ack.auth_info = data_blob_null;
1189 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 return dcesrv_bind_nak(call, 0);
1194 if (auth->auth_finished) {
1195 return dcesrv_auth_reply(call);
1198 subreq = gensec_update_send(call, call->event_ctx,
1199 auth->gensec_security,
1200 call->in_auth_info.credentials);
1201 if (subreq == NULL) {
1202 return NT_STATUS_NO_MEMORY;
1204 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1206 return dcesrv_conn_auth_wait_setup(conn);
1209 static void dcesrv_bind_done(struct tevent_req *subreq)
1211 struct dcesrv_call_state *call =
1212 tevent_req_callback_data(subreq,
1213 struct dcesrv_call_state);
1214 struct dcesrv_connection *conn = call->conn;
1217 status = gensec_update_recv(subreq, call,
1218 &call->out_auth_info->credentials);
1219 TALLOC_FREE(subreq);
1221 status = dcesrv_auth_complete(call, status);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 status = dcesrv_bind_nak(call, 0);
1224 dcesrv_conn_auth_wait_finished(conn, status);
1228 status = dcesrv_auth_reply(call);
1229 dcesrv_conn_auth_wait_finished(conn, status);
1233 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1235 struct ncacn_packet *pkt = &call->ack_pkt;
1236 struct data_blob_list_item *rep = NULL;
1239 rep = talloc_zero(call, struct data_blob_list_item);
1241 return NT_STATUS_NO_MEMORY;
1244 status = ncacn_push_auth(&rep->blob, call, pkt,
1245 call->out_auth_info);
1246 if (!NT_STATUS_IS_OK(status)) {
1250 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1252 DLIST_ADD_END(call->replies, rep);
1253 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1255 if (call->conn->call_list && call->conn->call_list->replies) {
1256 if (call->conn->transport.report_output_data) {
1257 call->conn->transport.report_output_data(call->conn);
1261 return NT_STATUS_OK;
1265 static void dcesrv_auth3_done(struct tevent_req *subreq);
1268 handle a auth3 request
1270 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1272 struct dcesrv_connection *conn = call->conn;
1273 struct dcesrv_auth *auth = &call->conn->auth_state;
1274 struct tevent_req *subreq = NULL;
1277 if (!call->conn->allow_auth3) {
1278 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1281 if (auth->auth_finished) {
1282 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1285 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1287 call->pkt.u.auth3.auth_info.length,
1288 0, /* required flags */
1289 DCERPC_PFC_FLAG_FIRST |
1290 DCERPC_PFC_FLAG_LAST |
1291 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1292 0x08 | /* this is not defined, but should be ignored */
1293 DCERPC_PFC_FLAG_CONC_MPX |
1294 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1295 DCERPC_PFC_FLAG_MAYBE |
1296 DCERPC_PFC_FLAG_OBJECT_UUID);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1301 /* handle the auth3 in the auth code */
1302 if (!dcesrv_auth_prepare_auth3(call)) {
1304 * we don't send a reply to a auth3 request,
1305 * except by a fault.
1307 * In anycase we mark the connection as
1310 auth->auth_invalid = true;
1311 if (call->fault_code != 0) {
1312 return dcesrv_fault_disconnect(call, call->fault_code);
1315 return NT_STATUS_OK;
1318 subreq = gensec_update_send(call, call->event_ctx,
1319 auth->gensec_security,
1320 call->in_auth_info.credentials);
1321 if (subreq == NULL) {
1322 return NT_STATUS_NO_MEMORY;
1324 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1326 return dcesrv_conn_auth_wait_setup(conn);
1329 static void dcesrv_auth3_done(struct tevent_req *subreq)
1331 struct dcesrv_call_state *call =
1332 tevent_req_callback_data(subreq,
1333 struct dcesrv_call_state);
1334 struct dcesrv_connection *conn = call->conn;
1335 struct dcesrv_auth *auth = &call->conn->auth_state;
1338 status = gensec_update_recv(subreq, call,
1339 &call->out_auth_info->credentials);
1340 TALLOC_FREE(subreq);
1342 status = dcesrv_auth_complete(call, status);
1343 if (!NT_STATUS_IS_OK(status)) {
1345 * we don't send a reply to a auth3 request,
1346 * except by a fault.
1348 * In anycase we mark the connection as
1351 auth->auth_invalid = true;
1352 if (call->fault_code != 0) {
1353 status = dcesrv_fault_disconnect(call, call->fault_code);
1354 dcesrv_conn_auth_wait_finished(conn, status);
1358 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1363 * we don't send a reply to a auth3 request.
1366 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1371 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1372 const struct dcerpc_bind *b,
1373 const struct dcerpc_ctx_list *ctx,
1374 struct dcerpc_ack_ctx *ack,
1376 const struct ndr_syntax_id *supported_transfer)
1378 uint32_t if_version;
1379 struct dcesrv_connection_context *context;
1380 const struct dcesrv_interface *iface;
1383 const struct ndr_syntax_id *selected_transfer = NULL;
1388 return NT_STATUS_INTERNAL_ERROR;
1391 return NT_STATUS_INTERNAL_ERROR;
1393 if (ctx->num_transfer_syntaxes < 1) {
1394 return NT_STATUS_INTERNAL_ERROR;
1397 return NT_STATUS_INTERNAL_ERROR;
1399 if (supported_transfer == NULL) {
1400 return NT_STATUS_INTERNAL_ERROR;
1403 switch (ack->result) {
1404 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1405 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1407 * We is already completed.
1409 return NT_STATUS_OK;
1414 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1415 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1417 if_version = ctx->abstract_syntax.if_version;
1418 uuid = ctx->abstract_syntax.uuid;
1420 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1421 if (iface == NULL) {
1422 char *uuid_str = GUID_string(call, &uuid);
1423 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1424 talloc_free(uuid_str);
1426 * We report this only via ack->result
1428 return NT_STATUS_OK;
1431 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1432 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1434 if (validate_only) {
1436 * We report this only via ack->result
1438 return NT_STATUS_OK;
1441 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1443 * we only do NDR encoded dcerpc for now.
1445 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1446 supported_transfer);
1448 selected_transfer = supported_transfer;
1453 context = dcesrv_find_context(call->conn, ctx->context_id);
1454 if (context != NULL) {
1455 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1456 &ctx->abstract_syntax);
1458 return NT_STATUS_RPC_PROTOCOL_ERROR;
1461 if (selected_transfer != NULL) {
1462 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1465 return NT_STATUS_RPC_PROTOCOL_ERROR;
1468 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1469 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1470 ack->syntax = context->transfer_syntax;
1474 * We report this only via ack->result
1476 return NT_STATUS_OK;
1479 if (selected_transfer == NULL) {
1481 * We report this only via ack->result
1483 return NT_STATUS_OK;
1486 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1487 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1489 /* add this context to the list of available context_ids */
1490 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1491 if (context == NULL) {
1492 return NT_STATUS_NO_MEMORY;
1494 context->conn = call->conn;
1495 context->context_id = ctx->context_id;
1496 context->iface = iface;
1497 context->transfer_syntax = *selected_transfer;
1498 context->private_data = NULL;
1499 DLIST_ADD(call->conn->contexts, context);
1500 call->context = context;
1501 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1503 dcesrv_prepare_context_auth(call);
1506 * Multiplex is supported by default
1508 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1510 status = iface->bind(call, iface, if_version);
1511 call->context = NULL;
1512 if (!NT_STATUS_IS_OK(status)) {
1513 /* we don't want to trigger the iface->unbind() hook */
1514 context->iface = NULL;
1515 talloc_free(context);
1517 * We report this only via ack->result
1519 return NT_STATUS_OK;
1522 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1523 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1524 ack->syntax = context->transfer_syntax;
1525 return NT_STATUS_OK;
1528 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1529 const struct dcerpc_bind *b,
1530 struct dcerpc_ack_ctx *ack_ctx_list)
1534 bool validate_only = false;
1535 bool preferred_ndr32;
1538 * Try to negotiate one new presentation context,
1539 * using our preferred transfer syntax.
1541 for (i = 0; i < b->num_contexts; i++) {
1542 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1543 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1545 status = dcesrv_check_or_create_context(call, b, c, a,
1547 call->conn->preferred_transfer);
1548 if (!NT_STATUS_IS_OK(status)) {
1552 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1554 * We managed to negotiate one context.
1558 validate_only = true;
1562 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1563 call->conn->preferred_transfer);
1564 if (preferred_ndr32) {
1568 return NT_STATUS_OK;
1572 * Try to negotiate one new presentation context,
1573 * using NDR 32 as fallback.
1575 for (i = 0; i < b->num_contexts; i++) {
1576 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1577 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1579 status = dcesrv_check_or_create_context(call, b, c, a,
1581 &ndr_transfer_syntax_ndr);
1582 if (!NT_STATUS_IS_OK(status)) {
1586 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1588 * We managed to negotiate one context.
1592 validate_only = true;
1596 return NT_STATUS_OK;
1599 static void dcesrv_alter_done(struct tevent_req *subreq);
1602 handle a alter context request
1604 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1606 struct dcesrv_connection *conn = call->conn;
1608 bool auth_ok = false;
1609 struct ncacn_packet *pkt = &call->ack_pkt;
1610 uint32_t extra_flags = 0;
1611 struct dcesrv_auth *auth = &call->conn->auth_state;
1612 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1613 struct tevent_req *subreq = NULL;
1616 if (!call->conn->allow_alter) {
1617 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1620 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1622 call->pkt.u.alter.auth_info.length,
1623 0, /* required flags */
1624 DCERPC_PFC_FLAG_FIRST |
1625 DCERPC_PFC_FLAG_LAST |
1626 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1627 0x08 | /* this is not defined, but should be ignored */
1628 DCERPC_PFC_FLAG_CONC_MPX |
1629 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1630 DCERPC_PFC_FLAG_MAYBE |
1631 DCERPC_PFC_FLAG_OBJECT_UUID);
1632 if (!NT_STATUS_IS_OK(status)) {
1633 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1636 auth_ok = dcesrv_auth_alter(call);
1638 if (call->fault_code != 0) {
1639 return dcesrv_fault_disconnect(call, call->fault_code);
1643 if (call->pkt.u.alter.num_contexts < 1) {
1644 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1647 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1648 call->pkt.u.alter.num_contexts);
1649 if (ack_ctx_list == NULL) {
1650 return NT_STATUS_NO_MEMORY;
1654 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1655 * dcesrv_check_or_create_context()) and do some protocol validation
1656 * and set sane defaults.
1658 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1659 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1660 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1662 if (c->num_transfer_syntaxes == 0) {
1663 return dcesrv_fault_disconnect(call,
1664 DCERPC_NCA_S_PROTO_ERROR);
1667 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1668 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1672 * Try to negotiate one new presentation context.
1674 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1675 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1676 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1678 if (!NT_STATUS_IS_OK(status)) {
1682 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1683 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1684 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1685 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1688 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1689 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1692 /* handle any authentication that is being requested */
1694 if (call->in_auth_info.auth_type != auth->auth_type) {
1695 return dcesrv_fault_disconnect(call,
1696 DCERPC_FAULT_SEC_PKG_ERROR);
1698 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1701 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1702 pkt->auth_length = 0;
1703 pkt->call_id = call->pkt.call_id;
1704 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1705 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1706 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1707 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1708 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1709 pkt->u.alter_resp.secondary_address = "";
1710 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1711 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1712 pkt->u.alter_resp.auth_info = data_blob_null;
1714 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1719 if (auth->auth_finished) {
1720 return dcesrv_auth_reply(call);
1723 subreq = gensec_update_send(call, call->event_ctx,
1724 auth->gensec_security,
1725 call->in_auth_info.credentials);
1726 if (subreq == NULL) {
1727 return NT_STATUS_NO_MEMORY;
1729 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1731 return dcesrv_conn_auth_wait_setup(conn);
1734 static void dcesrv_alter_done(struct tevent_req *subreq)
1736 struct dcesrv_call_state *call =
1737 tevent_req_callback_data(subreq,
1738 struct dcesrv_call_state);
1739 struct dcesrv_connection *conn = call->conn;
1742 status = gensec_update_recv(subreq, call,
1743 &call->out_auth_info->credentials);
1744 TALLOC_FREE(subreq);
1746 status = dcesrv_auth_complete(call, status);
1747 if (!NT_STATUS_IS_OK(status)) {
1748 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1749 dcesrv_conn_auth_wait_finished(conn, status);
1753 status = dcesrv_auth_reply(call);
1754 dcesrv_conn_auth_wait_finished(conn, status);
1759 possibly save the call for inspection with ndrdump
1761 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1765 const char *dump_dir;
1766 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1770 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1772 call->context->iface->name,
1773 call->pkt.u.request.opnum,
1775 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1776 DEBUG(0,("RPC SAVED %s\n", fname));
1782 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1784 TALLOC_CTX *frame = talloc_stackframe();
1785 const struct dcesrv_auth *auth = &call->conn->auth_state;
1786 const uint32_t bitmask1 = auth->client_hdr_signing ?
1787 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1788 const struct dcerpc_sec_vt_pcontext pcontext = {
1789 .abstract_syntax = call->context->iface->syntax_id,
1790 .transfer_syntax = call->context->transfer_syntax,
1792 const struct dcerpc_sec_vt_header2 header2 =
1793 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1794 enum ndr_err_code ndr_err;
1795 struct dcerpc_sec_verification_trailer *vt = NULL;
1796 NTSTATUS status = NT_STATUS_OK;
1799 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1801 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1803 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1804 status = ndr_map_error2ntstatus(ndr_err);
1808 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1809 &pcontext, &header2);
1811 status = NT_STATUS_ACCESS_DENIED;
1820 handle a dcerpc request packet
1822 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1824 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1825 struct dcesrv_auth *auth = &call->conn->auth_state;
1826 enum dcerpc_transport_t transport =
1827 dcerpc_binding_get_transport(endpoint->ep_description);
1828 struct ndr_pull *pull;
1831 if (!call->conn->allow_request) {
1832 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1835 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1836 if (auth->gensec_security != NULL &&
1837 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1838 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1841 if (call->context == NULL) {
1842 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1843 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1846 switch (auth->auth_level) {
1847 case DCERPC_AUTH_LEVEL_NONE:
1848 case DCERPC_AUTH_LEVEL_PACKET:
1849 case DCERPC_AUTH_LEVEL_INTEGRITY:
1850 case DCERPC_AUTH_LEVEL_PRIVACY:
1853 if (!call->context->allow_connect) {
1856 addr = tsocket_address_string(call->conn->remote_address,
1859 DEBUG(2, ("%s: restrict auth_level_connect access "
1860 "to [%s] with auth[type=0x%x,level=0x%x] "
1861 "on [%s] from [%s]\n",
1862 __func__, call->context->iface->name,
1865 derpc_transport_string_by_transport(transport),
1867 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1872 if (auth->auth_level < call->context->min_auth_level) {
1875 addr = tsocket_address_string(call->conn->remote_address, call);
1877 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1878 "to [%s] with auth[type=0x%x,level=0x%x] "
1879 "on [%s] from [%s]\n",
1881 call->context->min_auth_level,
1882 call->context->iface->name,
1885 derpc_transport_string_by_transport(transport),
1887 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1890 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1891 NT_STATUS_HAVE_NO_MEMORY(pull);
1893 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1895 call->ndr_pull = pull;
1897 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1898 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1901 status = dcesrv_check_verification_trailer(call);
1902 if (!NT_STATUS_IS_OK(status)) {
1903 uint32_t faultcode = DCERPC_FAULT_OTHER;
1904 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1905 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1907 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1908 nt_errstr(status)));
1909 return dcesrv_fault(call, faultcode);
1912 /* unravel the NDR for the packet */
1913 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1914 if (!NT_STATUS_IS_OK(status)) {
1915 uint8_t extra_flags = 0;
1916 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1917 /* we got an unknown call */
1918 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1919 call->pkt.u.request.opnum,
1920 call->context->iface->name));
1921 dcesrv_save_call(call, "unknown");
1922 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1924 dcesrv_save_call(call, "pullfail");
1926 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1929 if (pull->offset != pull->data_size) {
1930 dcesrv_save_call(call, "extrabytes");
1931 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1932 pull->data_size - pull->offset));
1935 /* call the dispatch function */
1936 status = call->context->iface->dispatch(call, call, call->r);
1937 if (!NT_STATUS_IS_OK(status)) {
1938 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1939 call->context->iface->name,
1940 call->pkt.u.request.opnum,
1941 dcerpc_errstr(pull, call->fault_code)));
1942 return dcesrv_fault(call, call->fault_code);
1945 /* add the call to the pending list */
1946 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1948 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1949 return NT_STATUS_OK;
1952 return dcesrv_reply(call);
1957 remove the call from the right list when freed
1959 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1961 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1965 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1967 return conn->local_address;
1970 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1972 return conn->remote_address;
1976 process some input to a dcerpc endpoint server.
1978 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1979 struct ncacn_packet *pkt,
1983 struct dcesrv_call_state *call;
1984 struct dcesrv_call_state *existing = NULL;
1986 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1988 data_blob_free(&blob);
1990 return NT_STATUS_NO_MEMORY;
1992 call->conn = dce_conn;
1993 call->event_ctx = dce_conn->event_ctx;
1994 call->msg_ctx = dce_conn->msg_ctx;
1995 call->state_flags = call->conn->state_flags;
1996 call->time = timeval_current();
1997 call->list = DCESRV_LIST_NONE;
1999 talloc_steal(call, pkt);
2000 talloc_steal(call, blob.data);
2003 talloc_set_destructor(call, dcesrv_call_dequeue);
2005 if (call->conn->allow_bind) {
2007 * Only one bind is possible per connection
2009 call->conn->allow_bind = false;
2010 return dcesrv_bind(call);
2013 /* we have to check the signing here, before combining the
2015 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2016 if (!call->conn->allow_request) {
2017 return dcesrv_fault_disconnect(call,
2018 DCERPC_NCA_S_PROTO_ERROR);
2021 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2023 call->pkt.u.request.stub_and_verifier.length,
2024 0, /* required_flags */
2025 DCERPC_PFC_FLAG_FIRST |
2026 DCERPC_PFC_FLAG_LAST |
2027 DCERPC_PFC_FLAG_PENDING_CANCEL |
2028 0x08 | /* this is not defined, but should be ignored */
2029 DCERPC_PFC_FLAG_CONC_MPX |
2030 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2031 DCERPC_PFC_FLAG_MAYBE |
2032 DCERPC_PFC_FLAG_OBJECT_UUID);
2033 if (!NT_STATUS_IS_OK(status)) {
2034 return dcesrv_fault_disconnect(call,
2035 DCERPC_NCA_S_PROTO_ERROR);
2038 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2040 * We don't use dcesrv_fault_disconnect()
2041 * here, because we don't want to set
2042 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2044 * Note that we don't check against the negotiated
2045 * max_recv_frag, but a hard coded value.
2047 dcesrv_call_disconnect_after(call,
2048 "dcesrv_auth_request - frag_length too large");
2049 return dcesrv_fault(call,
2050 DCERPC_NCA_S_PROTO_ERROR);
2053 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2054 if (dce_conn->pending_call_list != NULL) {
2056 * concurrent requests are only allowed
2057 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2059 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2060 dcesrv_call_disconnect_after(call,
2061 "dcesrv_auth_request - "
2062 "existing pending call without CONN_MPX");
2063 return dcesrv_fault(call,
2064 DCERPC_NCA_S_PROTO_ERROR);
2067 /* only one request is possible in the fragmented list */
2068 if (dce_conn->incoming_fragmented_call_list != NULL) {
2069 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2071 * Without DCERPC_PFC_FLAG_CONC_MPX
2072 * we need to return the FAULT on the
2073 * already existing call.
2075 * This is important to get the
2076 * call_id and context_id right.
2079 call = dce_conn->incoming_fragmented_call_list;
2081 dcesrv_call_disconnect_after(call,
2082 "dcesrv_auth_request - "
2083 "existing fragmented call");
2084 return dcesrv_fault(call,
2085 DCERPC_NCA_S_PROTO_ERROR);
2087 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2088 return dcesrv_fault_disconnect(call,
2089 DCERPC_FAULT_NO_CALL_ACTIVE);
2091 call->context = dcesrv_find_context(call->conn,
2092 call->pkt.u.request.context_id);
2093 if (call->context == NULL) {
2094 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2095 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2098 const struct dcerpc_request *nr = &call->pkt.u.request;
2099 const struct dcerpc_request *er = NULL;
2102 existing = dcesrv_find_fragmented_call(dce_conn,
2104 if (existing == NULL) {
2105 dcesrv_call_disconnect_after(call,
2106 "dcesrv_auth_request - "
2107 "no existing fragmented call");
2108 return dcesrv_fault(call,
2109 DCERPC_NCA_S_PROTO_ERROR);
2111 er = &existing->pkt.u.request;
2113 if (call->pkt.ptype != existing->pkt.ptype) {
2114 /* trying to play silly buggers are we? */
2115 return dcesrv_fault_disconnect(existing,
2116 DCERPC_NCA_S_PROTO_ERROR);
2118 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2121 return dcesrv_fault_disconnect(existing,
2122 DCERPC_NCA_S_PROTO_ERROR);
2124 if (nr->context_id != er->context_id) {
2125 return dcesrv_fault_disconnect(existing,
2126 DCERPC_NCA_S_PROTO_ERROR);
2128 if (nr->opnum != er->opnum) {
2129 return dcesrv_fault_disconnect(existing,
2130 DCERPC_NCA_S_PROTO_ERROR);
2135 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2137 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2139 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2140 payload_offset += 16;
2143 ok = dcesrv_auth_pkt_pull(call, &blob,
2144 0, /* required_flags */
2145 DCERPC_PFC_FLAG_FIRST |
2146 DCERPC_PFC_FLAG_LAST |
2147 DCERPC_PFC_FLAG_PENDING_CANCEL |
2148 0x08 | /* this is not defined, but should be ignored */
2149 DCERPC_PFC_FLAG_CONC_MPX |
2150 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2151 DCERPC_PFC_FLAG_MAYBE |
2152 DCERPC_PFC_FLAG_OBJECT_UUID,
2154 &call->pkt.u.request.stub_and_verifier);
2157 * We don't use dcesrv_fault_disconnect()
2158 * here, because we don't want to set
2159 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2161 dcesrv_call_disconnect_after(call,
2162 "dcesrv_auth_request - failed");
2163 if (call->fault_code == 0) {
2164 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2166 return dcesrv_fault(call, call->fault_code);
2170 /* see if this is a continued packet */
2171 if (existing != NULL) {
2172 struct dcerpc_request *er = &existing->pkt.u.request;
2173 const struct dcerpc_request *nr = &call->pkt.u.request;
2179 * Up to 4 MByte are allowed by all fragments
2181 available = dce_conn->max_total_request_size;
2182 if (er->stub_and_verifier.length > available) {
2183 dcesrv_call_disconnect_after(existing,
2184 "dcesrv_auth_request - existing payload too large");
2185 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2187 available -= er->stub_and_verifier.length;
2188 if (nr->alloc_hint > available) {
2189 dcesrv_call_disconnect_after(existing,
2190 "dcesrv_auth_request - alloc hint too large");
2191 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2193 if (nr->stub_and_verifier.length > available) {
2194 dcesrv_call_disconnect_after(existing,
2195 "dcesrv_auth_request - new payload too large");
2196 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2198 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2199 /* allocate at least 1 byte */
2200 alloc_hint = MAX(alloc_hint, 1);
2201 alloc_size = er->stub_and_verifier.length +
2202 nr->stub_and_verifier.length;
2203 alloc_size = MAX(alloc_size, alloc_hint);
2205 er->stub_and_verifier.data =
2206 talloc_realloc(existing,
2207 er->stub_and_verifier.data,
2208 uint8_t, alloc_size);
2209 if (er->stub_and_verifier.data == NULL) {
2211 return dcesrv_fault_with_flags(existing,
2212 DCERPC_FAULT_OUT_OF_RESOURCES,
2213 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2215 memcpy(er->stub_and_verifier.data +
2216 er->stub_and_verifier.length,
2217 nr->stub_and_verifier.data,
2218 nr->stub_and_verifier.length);
2219 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2221 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2227 /* this may not be the last pdu in the chain - if its isn't then
2228 just put it on the incoming_fragmented_call_list and wait for the rest */
2229 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2230 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2232 * Up to 4 MByte are allowed by all fragments
2234 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2235 dcesrv_call_disconnect_after(call,
2236 "dcesrv_auth_request - initial alloc hint too large");
2237 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2239 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2240 return NT_STATUS_OK;
2243 /* This removes any fragments we may have had stashed away */
2244 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2246 switch (call->pkt.ptype) {
2247 case DCERPC_PKT_BIND:
2248 status = dcesrv_bind_nak(call,
2249 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2251 case DCERPC_PKT_AUTH3:
2252 status = dcesrv_auth3(call);
2254 case DCERPC_PKT_ALTER:
2255 status = dcesrv_alter(call);
2257 case DCERPC_PKT_REQUEST:
2258 status = dcesrv_request(call);
2260 case DCERPC_PKT_CO_CANCEL:
2261 case DCERPC_PKT_ORPHANED:
2263 * Window just ignores CO_CANCEL and ORPHANED,
2266 status = NT_STATUS_OK;
2269 case DCERPC_PKT_BIND_ACK:
2270 case DCERPC_PKT_BIND_NAK:
2271 case DCERPC_PKT_ALTER_RESP:
2272 case DCERPC_PKT_RESPONSE:
2273 case DCERPC_PKT_FAULT:
2274 case DCERPC_PKT_SHUTDOWN:
2276 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2280 /* if we are going to be sending a reply then add
2281 it to the list of pending calls. We add it to the end to keep the call
2282 list in the order we will answer */
2283 if (!NT_STATUS_IS_OK(status)) {
2290 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2291 struct loadparm_context *lp_ctx,
2292 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2295 struct dcesrv_context *dce_ctx;
2298 if (!endpoint_servers) {
2299 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2300 return NT_STATUS_INTERNAL_ERROR;
2303 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2304 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2306 if (uid_wrapper_enabled()) {
2307 setenv("UID_WRAPPER_MYUID", "1", 1);
2309 dce_ctx->initial_euid = geteuid();
2310 if (uid_wrapper_enabled()) {
2311 unsetenv("UID_WRAPPER_MYUID");
2314 dce_ctx->endpoint_list = NULL;
2315 dce_ctx->lp_ctx = lp_ctx;
2316 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2317 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2318 dce_ctx->broken_connections = NULL;
2320 for (i=0;endpoint_servers[i];i++) {
2321 const struct dcesrv_endpoint_server *ep_server;
2323 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2325 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2326 return NT_STATUS_INTERNAL_ERROR;
2329 status = ep_server->init_server(dce_ctx, ep_server);
2330 if (!NT_STATUS_IS_OK(status)) {
2331 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2332 nt_errstr(status)));
2337 *_dce_ctx = dce_ctx;
2338 return NT_STATUS_OK;
2341 /* the list of currently registered DCERPC endpoint servers.
2343 static struct ep_server {
2344 struct dcesrv_endpoint_server *ep_server;
2345 } *ep_servers = NULL;
2346 static int num_ep_servers;
2349 register a DCERPC endpoint server.
2351 The 'name' can be later used by other backends to find the operations
2352 structure for this backend.
2355 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2358 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2359 /* its already registered! */
2360 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2362 return NT_STATUS_OBJECT_NAME_COLLISION;
2365 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2367 smb_panic("out of memory in dcerpc_register");
2370 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2371 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2375 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2378 return NT_STATUS_OK;
2382 return the operations structure for a named backend of the specified type
2384 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2388 for (i=0;i<num_ep_servers;i++) {
2389 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2390 return ep_servers[i].ep_server;
2397 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2399 static bool initialized;
2400 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2401 STATIC_dcerpc_server_MODULES_PROTO;
2402 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2403 init_module_fn *shared_init;
2410 shared_init = load_samba_modules(NULL, "dcerpc_server");
2412 run_init_functions(NULL, static_init);
2413 run_init_functions(NULL, shared_init);
2415 talloc_free(shared_init);
2419 return the DCERPC module version, and the size of some critical types
2420 This can be used by endpoint server modules to either detect compilation errors, or provide
2421 multiple implementations for different smbd compilation options in one module
2423 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2425 static const struct dcesrv_critical_sizes critical_sizes = {
2426 DCERPC_MODULE_VERSION,
2427 sizeof(struct dcesrv_context),
2428 sizeof(struct dcesrv_endpoint),
2429 sizeof(struct dcesrv_endpoint_server),
2430 sizeof(struct dcesrv_interface),
2431 sizeof(struct dcesrv_if_list),
2432 sizeof(struct dcesrv_connection),
2433 sizeof(struct dcesrv_call_state),
2434 sizeof(struct dcesrv_auth),
2435 sizeof(struct dcesrv_handle)
2438 return &critical_sizes;
2441 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2443 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2444 struct stream_connection *srv_conn;
2445 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2446 struct stream_connection);
2448 dce_conn->wait_send = NULL;
2449 dce_conn->wait_recv = NULL;
2450 dce_conn->wait_private = NULL;
2452 dce_conn->allow_bind = false;
2453 dce_conn->allow_auth3 = false;
2454 dce_conn->allow_alter = false;
2455 dce_conn->allow_request = false;
2457 if (dce_conn->pending_call_list == NULL) {
2458 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2460 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2461 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2465 if (dce_conn->terminate != NULL) {
2469 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2471 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2472 if (dce_conn->terminate == NULL) {
2473 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2475 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2478 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2480 struct dcesrv_connection *cur, *next;
2482 next = dce_ctx->broken_connections;
2483 while (next != NULL) {
2487 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2488 struct dcesrv_connection_context *context_cur, *context_next;
2490 context_next = cur->contexts;
2491 while (context_next != NULL) {
2492 context_cur = context_next;
2493 context_next = context_cur->next;
2495 dcesrv_connection_context_destructor(context_cur);
2499 dcesrv_terminate_connection(cur, cur->terminate);
2503 /* We need this include to be able to compile on some plateforms
2504 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2506 * It has to be that deep because otherwise we have a conflict on
2507 * const struct dcesrv_interface declaration.
2508 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2509 * which conflict with the bind used before.
2511 #include "system/network.h"
2513 struct dcesrv_sock_reply_state {
2514 struct dcesrv_connection *dce_conn;
2515 struct dcesrv_call_state *call;
2519 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2520 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2522 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2524 struct dcesrv_call_state *call;
2526 call = dce_conn->call_list;
2527 if (!call || !call->replies) {
2531 while (call->replies) {
2532 struct data_blob_list_item *rep = call->replies;
2533 struct dcesrv_sock_reply_state *substate;
2534 struct tevent_req *subreq;
2536 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2538 dcesrv_terminate_connection(dce_conn, "no memory");
2542 substate->dce_conn = dce_conn;
2543 substate->call = NULL;
2545 DLIST_REMOVE(call->replies, rep);
2547 if (call->replies == NULL && call->terminate_reason == NULL) {
2548 substate->call = call;
2551 substate->iov.iov_base = (void *) rep->blob.data;
2552 substate->iov.iov_len = rep->blob.length;
2554 subreq = tstream_writev_queue_send(substate,
2555 dce_conn->event_ctx,
2557 dce_conn->send_queue,
2560 dcesrv_terminate_connection(dce_conn, "no memory");
2563 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2567 if (call->terminate_reason != NULL) {
2568 struct tevent_req *subreq;
2570 subreq = tevent_queue_wait_send(call,
2571 dce_conn->event_ctx,
2572 dce_conn->send_queue);
2574 dcesrv_terminate_connection(dce_conn, __location__);
2577 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2581 DLIST_REMOVE(call->conn->call_list, call);
2582 call->list = DCESRV_LIST_NONE;
2585 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2587 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2588 struct dcesrv_sock_reply_state);
2592 struct dcesrv_call_state *call = substate->call;
2594 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2595 TALLOC_FREE(subreq);
2597 status = map_nt_error_from_unix_common(sys_errno);
2598 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2602 talloc_free(substate);
2608 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2610 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2612 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2613 struct dcesrv_call_state);
2617 /* make sure we stop send queue before removing subreq */
2618 tevent_queue_stop(call->conn->send_queue);
2620 ok = tevent_queue_wait_recv(subreq);
2621 TALLOC_FREE(subreq);
2623 dcesrv_terminate_connection(call->conn, __location__);
2627 /* disconnect after 200 usecs */
2628 tv = timeval_current_ofs_usec(200);
2629 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2630 if (subreq == NULL) {
2631 dcesrv_terminate_connection(call->conn, __location__);
2634 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2638 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2640 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2641 struct dcesrv_call_state);
2644 ok = tevent_wakeup_recv(subreq);
2645 TALLOC_FREE(subreq);
2647 dcesrv_terminate_connection(call->conn, __location__);
2651 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2654 struct dcesrv_socket_context {
2655 const struct dcesrv_endpoint *endpoint;
2656 struct dcesrv_context *dcesrv_ctx;
2660 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2662 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2665 struct dcesrv_socket_context *dcesrv_sock =
2666 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2667 enum dcerpc_transport_t transport =
2668 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2669 struct dcesrv_connection *dcesrv_conn = NULL;
2671 struct tevent_req *subreq;
2672 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2674 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2676 if (!srv_conn->session_info) {
2677 status = auth_anonymous_session_info(srv_conn,
2679 &srv_conn->session_info);
2680 if (!NT_STATUS_IS_OK(status)) {
2681 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2682 nt_errstr(status)));
2683 stream_terminate_connection(srv_conn, nt_errstr(status));
2689 * This fills in dcesrv_conn->endpoint with the endpoint
2690 * associated with the socket. From this point on we know
2691 * which (group of) services we are handling, but not the
2692 * specific interface.
2695 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2697 dcesrv_sock->endpoint,
2698 srv_conn->session_info,
2699 srv_conn->event.ctx,
2701 srv_conn->server_id,
2702 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2704 if (!NT_STATUS_IS_OK(status)) {
2705 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2706 nt_errstr(status)));
2707 stream_terminate_connection(srv_conn, nt_errstr(status));
2711 dcesrv_conn->transport.private_data = srv_conn;
2712 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2714 TALLOC_FREE(srv_conn->event.fde);
2716 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2717 if (!dcesrv_conn->send_queue) {
2718 status = NT_STATUS_NO_MEMORY;
2719 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2720 nt_errstr(status)));
2721 stream_terminate_connection(srv_conn, nt_errstr(status));
2725 if (transport == NCACN_NP) {
2726 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2727 &srv_conn->tstream);
2729 ret = tstream_bsd_existing_socket(dcesrv_conn,
2730 socket_get_fd(srv_conn->socket),
2731 &dcesrv_conn->stream);
2733 status = map_nt_error_from_unix_common(errno);
2734 DEBUG(0, ("dcesrv_sock_accept: "
2735 "failed to setup tstream: %s\n",
2736 nt_errstr(status)));
2737 stream_terminate_connection(srv_conn, nt_errstr(status));
2740 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2743 dcesrv_conn->local_address = srv_conn->local_address;
2744 dcesrv_conn->remote_address = srv_conn->remote_address;
2746 if (transport == NCALRPC) {
2751 sock_fd = socket_get_fd(srv_conn->socket);
2752 if (sock_fd == -1) {
2753 stream_terminate_connection(
2754 srv_conn, "socket_get_fd failed\n");
2758 ret = getpeereid(sock_fd, &uid, &gid);
2760 status = map_nt_error_from_unix_common(errno);
2761 DEBUG(0, ("dcesrv_sock_accept: "
2762 "getpeereid() failed for NCALRPC: %s\n",
2763 nt_errstr(status)));
2764 stream_terminate_connection(srv_conn, nt_errstr(status));
2767 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2768 struct tsocket_address *r = NULL;
2770 ret = tsocket_address_unix_from_path(dcesrv_conn,
2771 AS_SYSTEM_MAGIC_PATH_TOKEN,
2774 status = map_nt_error_from_unix_common(errno);
2775 DEBUG(0, ("dcesrv_sock_accept: "
2776 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2777 nt_errstr(status)));
2778 stream_terminate_connection(srv_conn, nt_errstr(status));
2781 dcesrv_conn->remote_address = r;
2785 srv_conn->private_data = dcesrv_conn;
2787 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2788 dcesrv_conn->event_ctx,
2789 dcesrv_conn->stream);
2791 status = NT_STATUS_NO_MEMORY;
2792 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2793 nt_errstr(status)));
2794 stream_terminate_connection(srv_conn, nt_errstr(status));
2797 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2802 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2804 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2806 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2807 struct dcesrv_connection);
2808 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2809 struct ncacn_packet *pkt;
2813 if (dce_conn->terminate) {
2815 * if the current connection is broken
2816 * we need to clean it up before any other connection
2818 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2819 dcesrv_cleanup_broken_connections(dce_ctx);
2823 dcesrv_cleanup_broken_connections(dce_ctx);
2825 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2827 TALLOC_FREE(subreq);
2828 if (!NT_STATUS_IS_OK(status)) {
2829 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2833 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2834 if (!NT_STATUS_IS_OK(status)) {
2835 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2840 * This is used to block the connection during
2841 * pending authentication.
2843 if (dce_conn->wait_send != NULL) {
2844 subreq = dce_conn->wait_send(dce_conn,
2845 dce_conn->event_ctx,
2846 dce_conn->wait_private);
2848 status = NT_STATUS_NO_MEMORY;
2849 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2852 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2856 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2857 dce_conn->event_ctx,
2860 status = NT_STATUS_NO_MEMORY;
2861 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2864 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2867 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2869 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2870 struct dcesrv_connection);
2871 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2874 if (dce_conn->terminate) {
2876 * if the current connection is broken
2877 * we need to clean it up before any other connection
2879 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2880 dcesrv_cleanup_broken_connections(dce_ctx);
2884 dcesrv_cleanup_broken_connections(dce_ctx);
2886 status = dce_conn->wait_recv(subreq);
2887 dce_conn->wait_send = NULL;
2888 dce_conn->wait_recv = NULL;
2889 dce_conn->wait_private = NULL;
2890 TALLOC_FREE(subreq);
2891 if (!NT_STATUS_IS_OK(status)) {
2892 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2896 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2897 dce_conn->event_ctx,
2900 status = NT_STATUS_NO_MEMORY;
2901 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2904 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2907 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2909 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2910 struct dcesrv_connection);
2911 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2914 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2916 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2917 struct dcesrv_connection);
2918 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2922 static const struct stream_server_ops dcesrv_stream_ops = {
2924 .accept_connection = dcesrv_sock_accept,
2925 .recv_handler = dcesrv_sock_recv,
2926 .send_handler = dcesrv_sock_send,
2929 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2930 struct loadparm_context *lp_ctx,
2931 struct dcesrv_endpoint *e,
2932 struct tevent_context *event_ctx,
2933 const struct model_ops *model_ops,
2934 void *process_context)
2936 struct dcesrv_socket_context *dcesrv_sock;
2939 const char *endpoint;
2941 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2942 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2944 /* remember the endpoint of this socket */
2945 dcesrv_sock->endpoint = e;
2946 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2948 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2950 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2951 model_ops, &dcesrv_stream_ops,
2952 "unix", endpoint, &port,
2953 lpcfg_socket_options(lp_ctx),
2954 dcesrv_sock, process_context);
2955 if (!NT_STATUS_IS_OK(status)) {
2956 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2957 endpoint, nt_errstr(status)));
2963 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2964 struct loadparm_context *lp_ctx,
2965 struct dcesrv_endpoint *e,
2966 struct tevent_context *event_ctx,
2967 const struct model_ops *model_ops,
2968 void *process_context)
2970 struct dcesrv_socket_context *dcesrv_sock;
2974 const char *endpoint;
2976 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2978 if (endpoint == NULL) {
2980 * No identifier specified: use DEFAULT.
2982 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2983 * no endpoint and let the epmapper worry about it.
2985 endpoint = "DEFAULT";
2986 status = dcerpc_binding_set_string_option(e->ep_description,
2989 if (!NT_STATUS_IS_OK(status)) {
2990 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2991 nt_errstr(status)));
2996 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2999 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3000 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3002 /* remember the endpoint of this socket */
3003 dcesrv_sock->endpoint = e;
3004 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3006 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3007 model_ops, &dcesrv_stream_ops,
3008 "unix", full_path, &port,
3009 lpcfg_socket_options(lp_ctx),
3010 dcesrv_sock, process_context);
3011 if (!NT_STATUS_IS_OK(status)) {
3012 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3013 endpoint, full_path, nt_errstr(status)));
3018 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3019 struct loadparm_context *lp_ctx,
3020 struct dcesrv_endpoint *e,
3021 struct tevent_context *event_ctx,
3022 const struct model_ops *model_ops,
3023 void *process_context)
3025 struct dcesrv_socket_context *dcesrv_sock;
3027 const char *endpoint;
3029 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3030 if (endpoint == NULL) {
3031 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3032 return NT_STATUS_INVALID_PARAMETER;
3035 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3036 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3038 /* remember the endpoint of this socket */
3039 dcesrv_sock->endpoint = e;
3040 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3042 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3043 model_ops, &dcesrv_stream_ops,
3045 dcesrv_sock, process_context);
3046 if (!NT_STATUS_IS_OK(status)) {
3047 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3048 endpoint, nt_errstr(status)));
3052 return NT_STATUS_OK;
3056 add a socket address to the list of events, one event per dcerpc endpoint
3058 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3059 struct dcesrv_endpoint *e,
3060 struct tevent_context *event_ctx,
3061 const struct model_ops *model_ops,
3062 const char *address,
3063 void *process_context)
3065 struct dcesrv_socket_context *dcesrv_sock;
3068 const char *endpoint;
3071 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3072 if (endpoint != NULL) {
3073 port = atoi(endpoint);
3076 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3077 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3079 /* remember the endpoint of this socket */
3080 dcesrv_sock->endpoint = e;
3081 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3083 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3084 model_ops, &dcesrv_stream_ops,
3085 "ip", address, &port,
3086 lpcfg_socket_options(dce_ctx->lp_ctx),
3087 dcesrv_sock, process_context);
3088 if (!NT_STATUS_IS_OK(status)) {
3089 struct dcesrv_if_list *iface;
3090 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3092 for (iface = e->interface_list; iface; iface = iface->next) {
3093 DEBUGADD(0, ("%s ", iface->iface.name));
3095 DEBUGADD(0, ("failed - %s",
3096 nt_errstr(status)));
3100 snprintf(port_str, sizeof(port_str), "%u", port);
3102 status = dcerpc_binding_set_string_option(e->ep_description,
3103 "endpoint", port_str);
3104 if (!NT_STATUS_IS_OK(status)) {
3105 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3106 port_str, nt_errstr(status)));
3109 struct dcesrv_if_list *iface;
3110 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3111 address, port_str));
3112 for (iface = e->interface_list; iface; iface = iface->next) {
3113 DEBUGADD(4, ("%s ", iface->iface.name));
3115 DEBUGADD(4, ("\n"));
3118 return NT_STATUS_OK;
3121 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3123 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3124 struct loadparm_context *lp_ctx,
3125 struct dcesrv_endpoint *e,
3126 struct tevent_context *event_ctx,
3127 const struct model_ops *model_ops,
3128 void *process_context)
3132 /* Add TCP/IP sockets */
3133 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3136 struct interface *ifaces;
3138 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3140 num_interfaces = iface_list_count(ifaces);
3141 for(i = 0; i < num_interfaces; i++) {
3142 const char *address = iface_list_n_ip(ifaces, i);
3143 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3146 NT_STATUS_NOT_OK_RETURN(status);
3151 size_t num_binds = 0;
3152 wcard = iface_list_wildcard(dce_ctx);
3153 NT_STATUS_HAVE_NO_MEMORY(wcard);
3154 for (i=0; wcard[i]; i++) {
3155 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3156 model_ops, wcard[i],
3158 if (NT_STATUS_IS_OK(status)) {
3163 if (num_binds == 0) {
3164 return NT_STATUS_INVALID_PARAMETER_MIX;
3168 return NT_STATUS_OK;
3171 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3172 struct loadparm_context *lp_ctx,
3173 struct dcesrv_endpoint *e,
3174 struct tevent_context *event_ctx,
3175 const struct model_ops *model_ops,
3176 void *process_context)
3178 enum dcerpc_transport_t transport =
3179 dcerpc_binding_get_transport(e->ep_description);
3181 switch (transport) {
3182 case NCACN_UNIX_STREAM:
3183 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3184 model_ops, process_context);
3187 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3188 model_ops, process_context);
3191 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3192 model_ops, process_context);
3195 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3196 model_ops, process_context);
3199 return NT_STATUS_NOT_SUPPORTED;
3205 * retrieve credentials from a dce_call
3207 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3209 struct dcesrv_auth *auth = &dce_call->conn->auth_state;
3210 return auth->session_info->credentials;
3214 * returns true if this is an authenticated call
3216 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3218 struct dcesrv_auth *auth = &dce_call->conn->auth_state;
3219 enum security_user_level level;
3220 level = security_session_user_level(auth->session_info, NULL);
3221 return level >= SECURITY_USER;
3225 * retrieve account_name for a dce_call
3227 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3229 struct dcesrv_auth *auth = &dce_call->conn->auth_state;
3230 return auth->session_info->info->account_name;
3234 * retrieve session_info from a dce_call
3236 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3238 struct dcesrv_auth *auth = &dce_call->conn->auth_state;
3239 return auth->session_info;
3243 * retrieve auth type/level from a dce_call
3245 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3246 enum dcerpc_AuthType *auth_type,
3247 enum dcerpc_AuthLevel *auth_level)
3249 struct dcesrv_auth *auth = &dce_call->conn->auth_state;
3251 if (auth_type != NULL) {
3252 *auth_type = auth->auth_type;
3254 if (auth_level != NULL) {
3255 *auth_level = auth->auth_level;