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 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
478 DATA_BLOB *session_key)
480 struct dcesrv_auth *auth = &p->auth_state;
482 return dcesrv_session_info_session_key(auth, session_key);
486 * Fetch the authentication session key if available.
488 * This is the key generated by a gensec authentication.
491 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
492 DATA_BLOB *session_key)
494 struct dcesrv_auth *auth = &call->conn->auth_state;
496 return dcesrv_session_info_session_key(auth, session_key);
500 fetch the user session key - may be default (above) or the SMB session key
502 The key is always truncated to 16 bytes
504 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
505 DATA_BLOB *session_key)
507 struct dcesrv_auth *auth = &p->auth_state;
510 if (auth->session_key == NULL) {
511 return NT_STATUS_NO_USER_SESSION_KEY;
514 status = auth->session_key(p, session_key);
515 if (!NT_STATUS_IS_OK(status)) {
519 session_key->length = MIN(session_key->length, 16);
525 * Fetch the transport session key if available.
526 * Typically this is the SMB session key
527 * or a fixed key for local transports.
529 * The key is always truncated to 16 bytes.
531 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
532 DATA_BLOB *session_key)
534 return dcesrv_fetch_session_key(call->conn, session_key);
538 connect to a dcerpc endpoint
540 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
542 const struct dcesrv_endpoint *ep,
543 struct auth_session_info *session_info,
544 struct tevent_context *event_ctx,
545 struct imessaging_context *msg_ctx,
546 struct server_id server_id,
547 uint32_t state_flags,
548 struct dcesrv_connection **_p)
550 struct dcesrv_connection *p;
553 return NT_STATUS_ACCESS_DENIED;
556 p = talloc_zero(mem_ctx, struct dcesrv_connection);
557 NT_STATUS_HAVE_NO_MEMORY(p);
559 if (!talloc_reference(p, session_info)) {
561 return NT_STATUS_NO_MEMORY;
564 p->dce_ctx = dce_ctx;
566 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
567 p->auth_state.session_info = session_info;
568 p->auth_state.session_key = dcesrv_generic_session_key;
569 p->event_ctx = event_ctx;
570 p->msg_ctx = msg_ctx;
571 p->server_id = server_id;
572 p->state_flags = state_flags;
573 p->allow_bind = true;
574 p->max_recv_frag = 5840;
575 p->max_xmit_frag = 5840;
576 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
579 * For now we only support NDR32.
581 p->preferred_transfer = &ndr_transfer_syntax_ndr;
588 move a call from an existing linked list to the specified list. This
589 prevents bugs where we forget to remove the call from a previous
592 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
593 enum dcesrv_call_list list)
595 switch (call->list) {
596 case DCESRV_LIST_NONE:
598 case DCESRV_LIST_CALL_LIST:
599 DLIST_REMOVE(call->conn->call_list, call);
601 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
602 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
604 case DCESRV_LIST_PENDING_CALL_LIST:
605 DLIST_REMOVE(call->conn->pending_call_list, call);
610 case DCESRV_LIST_NONE:
612 case DCESRV_LIST_CALL_LIST:
613 DLIST_ADD_END(call->conn->call_list, call);
615 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
616 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
618 case DCESRV_LIST_PENDING_CALL_LIST:
619 DLIST_ADD_END(call->conn->pending_call_list, call);
624 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
627 if (call->conn->terminate != NULL) {
631 call->conn->allow_bind = false;
632 call->conn->allow_alter = false;
633 call->conn->allow_auth3 = false;
634 call->conn->allow_request = false;
636 call->terminate_reason = talloc_strdup(call, reason);
637 if (call->terminate_reason == NULL) {
638 call->terminate_reason = __location__;
643 return a dcerpc bind_nak
645 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
647 struct ncacn_packet pkt;
648 struct dcerpc_bind_nak_version version;
649 struct data_blob_list_item *rep;
651 static const uint8_t _pad[3] = { 0, };
654 * We add the call to the pending_call_list
655 * in order to defer the termination.
657 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
659 /* setup a bind_nak */
660 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
662 pkt.call_id = call->pkt.call_id;
663 pkt.ptype = DCERPC_PKT_BIND_NAK;
664 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
665 pkt.u.bind_nak.reject_reason = reason;
666 version.rpc_vers = 5;
667 version.rpc_vers_minor = 0;
668 pkt.u.bind_nak.num_versions = 1;
669 pkt.u.bind_nak.versions = &version;
670 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
672 rep = talloc_zero(call, struct data_blob_list_item);
674 return NT_STATUS_NO_MEMORY;
677 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
678 if (!NT_STATUS_IS_OK(status)) {
682 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
684 DLIST_ADD_END(call->replies, rep);
685 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
687 if (call->conn->call_list && call->conn->call_list->replies) {
688 if (call->conn->transport.report_output_data) {
689 call->conn->transport.report_output_data(call->conn);
696 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
700 * We add the call to the pending_call_list
701 * in order to defer the termination.
703 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
705 return dcesrv_fault_with_flags(call, fault_code,
706 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
709 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
711 DLIST_REMOVE(c->conn->contexts, c);
713 if (c->iface && c->iface->unbind) {
714 c->iface->unbind(c, c->iface);
721 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
723 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
724 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
725 enum dcerpc_transport_t transport =
726 dcerpc_binding_get_transport(endpoint->ep_description);
727 struct dcesrv_connection_context *context = dce_call->context;
728 const struct dcesrv_interface *iface = context->iface;
730 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
732 if (transport == NCALRPC) {
733 context->allow_connect = true;
738 * allow overwrite per interface
739 * allow dcerpc auth level connect:<interface>
741 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
742 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
743 "allow dcerpc auth level connect",
745 context->allow_connect);
748 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
749 const struct dcesrv_interface *iface)
751 if (dce_call->context == NULL) {
752 return NT_STATUS_INTERNAL_ERROR;
756 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
757 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
759 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
763 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
764 const struct dcesrv_interface *iface)
766 if (dce_call->context == NULL) {
767 return NT_STATUS_INTERNAL_ERROR;
770 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
774 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
775 const struct dcesrv_interface *iface)
777 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
778 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
779 enum dcerpc_transport_t transport =
780 dcerpc_binding_get_transport(endpoint->ep_description);
781 struct dcesrv_connection_context *context = dce_call->context;
783 if (context == NULL) {
784 return NT_STATUS_INTERNAL_ERROR;
787 if (transport == NCALRPC) {
788 context->allow_connect = true;
793 * allow overwrite per interface
794 * allow dcerpc auth level connect:<interface>
796 context->allow_connect = false;
797 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
798 "allow dcerpc auth level connect",
800 context->allow_connect);
804 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
805 const struct dcesrv_interface *iface)
807 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
808 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
809 enum dcerpc_transport_t transport =
810 dcerpc_binding_get_transport(endpoint->ep_description);
811 struct dcesrv_connection_context *context = dce_call->context;
813 if (context == NULL) {
814 return NT_STATUS_INTERNAL_ERROR;
817 if (transport == NCALRPC) {
818 context->allow_connect = true;
823 * allow overwrite per interface
824 * allow dcerpc auth level connect:<interface>
826 context->allow_connect = true;
827 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
828 "allow dcerpc auth level connect",
830 context->allow_connect);
834 struct dcesrv_conn_auth_wait_context {
835 struct tevent_req *req;
840 struct dcesrv_conn_auth_wait_state {
844 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
845 struct tevent_context *ev,
848 struct dcesrv_conn_auth_wait_context *auth_wait =
849 talloc_get_type_abort(private_data,
850 struct dcesrv_conn_auth_wait_context);
851 struct tevent_req *req = NULL;
852 struct dcesrv_conn_auth_wait_state *state = NULL;
854 req = tevent_req_create(mem_ctx, &state,
855 struct dcesrv_conn_auth_wait_state);
859 auth_wait->req = req;
861 tevent_req_defer_callback(req, ev);
863 if (!auth_wait->done) {
867 if (tevent_req_nterror(req, auth_wait->status)) {
868 return tevent_req_post(req, ev);
871 tevent_req_done(req);
872 return tevent_req_post(req, ev);
875 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
877 return tevent_req_simple_recv_ntstatus(req);
880 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
882 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
884 if (conn->wait_send != NULL) {
885 return NT_STATUS_INTERNAL_ERROR;
888 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
889 if (auth_wait == NULL) {
890 return NT_STATUS_NO_MEMORY;
893 conn->wait_private = auth_wait;
894 conn->wait_send = dcesrv_conn_auth_wait_send;
895 conn->wait_recv = dcesrv_conn_auth_wait_recv;
899 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
902 struct dcesrv_conn_auth_wait_context *auth_wait =
903 talloc_get_type_abort(conn->wait_private,
904 struct dcesrv_conn_auth_wait_context);
906 auth_wait->done = true;
907 auth_wait->status = status;
909 if (auth_wait->req == NULL) {
913 if (tevent_req_nterror(auth_wait->req, status)) {
917 tevent_req_done(auth_wait->req);
920 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
922 static void dcesrv_bind_done(struct tevent_req *subreq);
925 handle a bind request
927 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
929 struct dcesrv_connection *conn = call->conn;
930 struct ncacn_packet *pkt = &call->ack_pkt;
932 uint32_t extra_flags = 0;
933 uint16_t max_req = 0;
934 uint16_t max_rep = 0;
935 const char *ep_prefix = "";
936 const char *endpoint = NULL;
937 struct dcesrv_auth *auth = &call->conn->auth_state;
938 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
939 struct dcerpc_ack_ctx *ack_features = NULL;
940 struct tevent_req *subreq = NULL;
943 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
945 call->pkt.u.bind.auth_info.length,
946 0, /* required flags */
947 DCERPC_PFC_FLAG_FIRST |
948 DCERPC_PFC_FLAG_LAST |
949 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
950 0x08 | /* this is not defined, but should be ignored */
951 DCERPC_PFC_FLAG_CONC_MPX |
952 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
953 DCERPC_PFC_FLAG_MAYBE |
954 DCERPC_PFC_FLAG_OBJECT_UUID);
955 if (!NT_STATUS_IS_OK(status)) {
956 return dcesrv_bind_nak(call,
957 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
960 /* max_recv_frag and max_xmit_frag result always in the same value! */
961 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
962 call->pkt.u.bind.max_recv_frag);
964 * The values are between 2048 and 5840 tested against Windows 2012R2
965 * via ncacn_ip_tcp on port 135.
967 max_req = MAX(2048, max_req);
968 max_rep = MIN(max_req, call->conn->max_recv_frag);
969 /* They are truncated to an 8 byte boundary. */
972 /* max_recv_frag and max_xmit_frag result always in the same value! */
973 call->conn->max_recv_frag = max_rep;
974 call->conn->max_xmit_frag = max_rep;
977 if provided, check the assoc_group is valid
979 if (call->pkt.u.bind.assoc_group_id != 0) {
980 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
982 call->pkt.u.bind.assoc_group_id);
984 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
985 call->conn->dce_ctx);
989 * The NETLOGON server does not use handles and so
990 * there is no need to support association groups, but
991 * we need to give back a number regardless.
993 * We have to do this when it is not run as a single process,
994 * because then it can't see the other valid association
995 * groups. We handle this genericly for all endpoints not
996 * running in single process mode.
998 * We know which endpoint we are on even before checking the
999 * iface UUID, so for simplicity we enforce the same policy
1000 * for all interfaces on the endpoint.
1002 * This means that where NETLOGON
1003 * shares an endpoint (such as ncalrpc or of 'lsa over
1004 * netlogon' is set) we will still check association groups.
1008 if (call->conn->assoc_group == NULL &&
1009 !call->conn->endpoint->use_single_process) {
1010 call->conn->assoc_group
1011 = dcesrv_assoc_group_new(call->conn,
1012 call->conn->dce_ctx);
1014 if (call->conn->assoc_group == NULL) {
1015 return dcesrv_bind_nak(call, 0);
1018 if (call->pkt.u.bind.num_contexts < 1) {
1019 return dcesrv_bind_nak(call, 0);
1022 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1023 call->pkt.u.bind.num_contexts);
1024 if (ack_ctx_list == NULL) {
1025 return dcesrv_bind_nak(call, 0);
1029 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1030 * dcesrv_check_or_create_context()) and do some protocol validation
1031 * and set sane defaults.
1033 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1034 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1035 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1036 bool is_feature = false;
1037 uint64_t features = 0;
1039 if (c->num_transfer_syntaxes == 0) {
1040 return dcesrv_bind_nak(call, 0);
1043 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1044 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1047 * It's only treated as bind time feature request, if the first
1048 * transfer_syntax matches, all others are ignored.
1050 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1056 if (ack_features != NULL) {
1058 * Only one bind time feature context is allowed.
1060 return dcesrv_bind_nak(call, 0);
1064 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1065 a->reason.negotiate = 0;
1066 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1067 /* not supported yet */
1069 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1070 a->reason.negotiate |=
1071 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1074 call->conn->bind_time_features = a->reason.negotiate;
1078 * Try to negotiate one new presentation context.
1080 * Deep in here we locate the iface (by uuid) that the client
1081 * requested, from the list of interfaces on the
1082 * call->conn->endpoint, and call iface->bind() on that iface.
1084 * call->conn was set up at the accept() of the socket, and
1085 * call->conn->endpoint has a list of interfaces restricted to
1086 * this port or pipe.
1088 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1089 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1090 return dcesrv_bind_nak(call, 0);
1092 if (!NT_STATUS_IS_OK(status)) {
1097 * At this point we still don't know which interface (eg
1098 * netlogon, lsa, drsuapi) the caller requested in this bind!
1099 * The most recently added context is available as the first
1100 * element in the linked list at call->conn->contexts, that is
1101 * call->conn->contexts->iface, but they may not have
1102 * requested one at all!
1105 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1106 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1107 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1108 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1111 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1112 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1116 * After finding the interface and setting up the NDR
1117 * transport negotiation etc, handle any authentication that
1118 * is being requested.
1120 if (!dcesrv_auth_bind(call)) {
1122 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1124 * With DCERPC_AUTH_LEVEL_NONE, we get the
1125 * reject_reason in auth->auth_context_id.
1127 return dcesrv_bind_nak(call, auth->auth_context_id);
1131 * This must a be a temporary failure e.g. talloc or invalid
1132 * configuration, e.g. no machine account.
1134 return dcesrv_bind_nak(call,
1135 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1138 /* setup a bind_ack */
1139 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1140 pkt->auth_length = 0;
1141 pkt->call_id = call->pkt.call_id;
1142 pkt->ptype = DCERPC_PKT_BIND_ACK;
1143 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1144 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1145 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1146 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1148 endpoint = dcerpc_binding_get_string_option(
1149 call->conn->endpoint->ep_description,
1151 if (endpoint == NULL) {
1155 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1157 * TODO: check if this is really needed
1159 * Or if we should fix this in our idl files.
1161 ep_prefix = "\\PIPE\\";
1165 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1168 if (pkt->u.bind_ack.secondary_address == NULL) {
1169 return NT_STATUS_NO_MEMORY;
1171 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1172 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1173 pkt->u.bind_ack.auth_info = data_blob_null;
1175 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1176 if (!NT_STATUS_IS_OK(status)) {
1177 return dcesrv_bind_nak(call, 0);
1180 if (auth->auth_finished) {
1181 return dcesrv_auth_reply(call);
1184 subreq = gensec_update_send(call, call->event_ctx,
1185 auth->gensec_security,
1186 call->in_auth_info.credentials);
1187 if (subreq == NULL) {
1188 return NT_STATUS_NO_MEMORY;
1190 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1192 return dcesrv_conn_auth_wait_setup(conn);
1195 static void dcesrv_bind_done(struct tevent_req *subreq)
1197 struct dcesrv_call_state *call =
1198 tevent_req_callback_data(subreq,
1199 struct dcesrv_call_state);
1200 struct dcesrv_connection *conn = call->conn;
1203 status = gensec_update_recv(subreq, call,
1204 &call->out_auth_info->credentials);
1205 TALLOC_FREE(subreq);
1207 status = dcesrv_auth_complete(call, status);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 status = dcesrv_bind_nak(call, 0);
1210 dcesrv_conn_auth_wait_finished(conn, status);
1214 status = dcesrv_auth_reply(call);
1215 dcesrv_conn_auth_wait_finished(conn, status);
1219 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1221 struct ncacn_packet *pkt = &call->ack_pkt;
1222 struct data_blob_list_item *rep = NULL;
1225 rep = talloc_zero(call, struct data_blob_list_item);
1227 return NT_STATUS_NO_MEMORY;
1230 status = ncacn_push_auth(&rep->blob, call, pkt,
1231 call->out_auth_info);
1232 if (!NT_STATUS_IS_OK(status)) {
1236 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1238 DLIST_ADD_END(call->replies, rep);
1239 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1241 if (call->conn->call_list && call->conn->call_list->replies) {
1242 if (call->conn->transport.report_output_data) {
1243 call->conn->transport.report_output_data(call->conn);
1247 return NT_STATUS_OK;
1251 static void dcesrv_auth3_done(struct tevent_req *subreq);
1254 handle a auth3 request
1256 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1258 struct dcesrv_connection *conn = call->conn;
1259 struct dcesrv_auth *auth = &call->conn->auth_state;
1260 struct tevent_req *subreq = NULL;
1263 if (!call->conn->allow_auth3) {
1264 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1267 if (call->conn->auth_state.auth_finished) {
1268 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1271 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1273 call->pkt.u.auth3.auth_info.length,
1274 0, /* required flags */
1275 DCERPC_PFC_FLAG_FIRST |
1276 DCERPC_PFC_FLAG_LAST |
1277 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1278 0x08 | /* this is not defined, but should be ignored */
1279 DCERPC_PFC_FLAG_CONC_MPX |
1280 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1281 DCERPC_PFC_FLAG_MAYBE |
1282 DCERPC_PFC_FLAG_OBJECT_UUID);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1287 /* handle the auth3 in the auth code */
1288 if (!dcesrv_auth_prepare_auth3(call)) {
1290 * we don't send a reply to a auth3 request,
1291 * except by a fault.
1293 * In anycase we mark the connection as
1296 call->conn->auth_state.auth_invalid = true;
1297 if (call->fault_code != 0) {
1298 return dcesrv_fault_disconnect(call, call->fault_code);
1301 return NT_STATUS_OK;
1304 subreq = gensec_update_send(call, call->event_ctx,
1305 auth->gensec_security,
1306 call->in_auth_info.credentials);
1307 if (subreq == NULL) {
1308 return NT_STATUS_NO_MEMORY;
1310 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1312 return dcesrv_conn_auth_wait_setup(conn);
1315 static void dcesrv_auth3_done(struct tevent_req *subreq)
1317 struct dcesrv_call_state *call =
1318 tevent_req_callback_data(subreq,
1319 struct dcesrv_call_state);
1320 struct dcesrv_connection *conn = call->conn;
1323 status = gensec_update_recv(subreq, call,
1324 &call->out_auth_info->credentials);
1325 TALLOC_FREE(subreq);
1327 status = dcesrv_auth_complete(call, status);
1328 if (!NT_STATUS_IS_OK(status)) {
1330 * we don't send a reply to a auth3 request,
1331 * except by a fault.
1333 * In anycase we mark the connection as
1336 call->conn->auth_state.auth_invalid = true;
1337 if (call->fault_code != 0) {
1338 status = dcesrv_fault_disconnect(call, call->fault_code);
1339 dcesrv_conn_auth_wait_finished(conn, status);
1343 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1348 * we don't send a reply to a auth3 request.
1351 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1356 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1357 const struct dcerpc_bind *b,
1358 const struct dcerpc_ctx_list *ctx,
1359 struct dcerpc_ack_ctx *ack,
1361 const struct ndr_syntax_id *supported_transfer)
1363 uint32_t if_version;
1364 struct dcesrv_connection_context *context;
1365 const struct dcesrv_interface *iface;
1368 const struct ndr_syntax_id *selected_transfer = NULL;
1373 return NT_STATUS_INTERNAL_ERROR;
1376 return NT_STATUS_INTERNAL_ERROR;
1378 if (ctx->num_transfer_syntaxes < 1) {
1379 return NT_STATUS_INTERNAL_ERROR;
1382 return NT_STATUS_INTERNAL_ERROR;
1384 if (supported_transfer == NULL) {
1385 return NT_STATUS_INTERNAL_ERROR;
1388 switch (ack->result) {
1389 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1390 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1392 * We is already completed.
1394 return NT_STATUS_OK;
1399 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1400 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1402 if_version = ctx->abstract_syntax.if_version;
1403 uuid = ctx->abstract_syntax.uuid;
1405 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1406 if (iface == NULL) {
1407 char *uuid_str = GUID_string(call, &uuid);
1408 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1409 talloc_free(uuid_str);
1411 * We report this only via ack->result
1413 return NT_STATUS_OK;
1416 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1417 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1419 if (validate_only) {
1421 * We report this only via ack->result
1423 return NT_STATUS_OK;
1426 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1428 * we only do NDR encoded dcerpc for now.
1430 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1431 supported_transfer);
1433 selected_transfer = supported_transfer;
1438 context = dcesrv_find_context(call->conn, ctx->context_id);
1439 if (context != NULL) {
1440 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1441 &ctx->abstract_syntax);
1443 return NT_STATUS_RPC_PROTOCOL_ERROR;
1446 if (selected_transfer != NULL) {
1447 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1450 return NT_STATUS_RPC_PROTOCOL_ERROR;
1453 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1454 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1455 ack->syntax = context->transfer_syntax;
1459 * We report this only via ack->result
1461 return NT_STATUS_OK;
1464 if (selected_transfer == NULL) {
1466 * We report this only via ack->result
1468 return NT_STATUS_OK;
1471 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1472 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1474 /* add this context to the list of available context_ids */
1475 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1476 if (context == NULL) {
1477 return NT_STATUS_NO_MEMORY;
1479 context->conn = call->conn;
1480 context->context_id = ctx->context_id;
1481 context->iface = iface;
1482 context->transfer_syntax = *selected_transfer;
1483 context->private_data = NULL;
1484 DLIST_ADD(call->conn->contexts, context);
1485 call->context = context;
1486 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1488 dcesrv_prepare_context_auth(call);
1491 * Multiplex is supported by default
1493 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1495 status = iface->bind(call, iface, if_version);
1496 call->context = NULL;
1497 if (!NT_STATUS_IS_OK(status)) {
1498 /* we don't want to trigger the iface->unbind() hook */
1499 context->iface = NULL;
1500 talloc_free(context);
1502 * We report this only via ack->result
1504 return NT_STATUS_OK;
1507 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1508 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1509 ack->syntax = context->transfer_syntax;
1510 return NT_STATUS_OK;
1513 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1514 const struct dcerpc_bind *b,
1515 struct dcerpc_ack_ctx *ack_ctx_list)
1519 bool validate_only = false;
1520 bool preferred_ndr32;
1523 * Try to negotiate one new presentation context,
1524 * using our preferred transfer syntax.
1526 for (i = 0; i < b->num_contexts; i++) {
1527 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1528 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1530 status = dcesrv_check_or_create_context(call, b, c, a,
1532 call->conn->preferred_transfer);
1533 if (!NT_STATUS_IS_OK(status)) {
1537 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1539 * We managed to negotiate one context.
1543 validate_only = true;
1547 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1548 call->conn->preferred_transfer);
1549 if (preferred_ndr32) {
1553 return NT_STATUS_OK;
1557 * Try to negotiate one new presentation context,
1558 * using NDR 32 as fallback.
1560 for (i = 0; i < b->num_contexts; i++) {
1561 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1562 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1564 status = dcesrv_check_or_create_context(call, b, c, a,
1566 &ndr_transfer_syntax_ndr);
1567 if (!NT_STATUS_IS_OK(status)) {
1571 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1573 * We managed to negotiate one context.
1577 validate_only = true;
1581 return NT_STATUS_OK;
1584 static void dcesrv_alter_done(struct tevent_req *subreq);
1587 handle a alter context request
1589 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1591 struct dcesrv_connection *conn = call->conn;
1593 bool auth_ok = false;
1594 struct ncacn_packet *pkt = &call->ack_pkt;
1595 uint32_t extra_flags = 0;
1596 struct dcesrv_auth *auth = &call->conn->auth_state;
1597 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1598 struct tevent_req *subreq = NULL;
1601 if (!call->conn->allow_alter) {
1602 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1605 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1607 call->pkt.u.alter.auth_info.length,
1608 0, /* required flags */
1609 DCERPC_PFC_FLAG_FIRST |
1610 DCERPC_PFC_FLAG_LAST |
1611 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1612 0x08 | /* this is not defined, but should be ignored */
1613 DCERPC_PFC_FLAG_CONC_MPX |
1614 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1615 DCERPC_PFC_FLAG_MAYBE |
1616 DCERPC_PFC_FLAG_OBJECT_UUID);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1621 auth_ok = dcesrv_auth_alter(call);
1623 if (call->fault_code != 0) {
1624 return dcesrv_fault_disconnect(call, call->fault_code);
1628 if (call->pkt.u.alter.num_contexts < 1) {
1629 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1632 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1633 call->pkt.u.alter.num_contexts);
1634 if (ack_ctx_list == NULL) {
1635 return NT_STATUS_NO_MEMORY;
1639 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1640 * dcesrv_check_or_create_context()) and do some protocol validation
1641 * and set sane defaults.
1643 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1644 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1645 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1647 if (c->num_transfer_syntaxes == 0) {
1648 return dcesrv_fault_disconnect(call,
1649 DCERPC_NCA_S_PROTO_ERROR);
1652 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1653 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1657 * Try to negotiate one new presentation context.
1659 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1660 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1661 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1663 if (!NT_STATUS_IS_OK(status)) {
1667 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1668 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1669 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1670 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1673 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1674 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1677 /* handle any authentication that is being requested */
1679 if (call->in_auth_info.auth_type !=
1680 call->conn->auth_state.auth_type)
1682 return dcesrv_fault_disconnect(call,
1683 DCERPC_FAULT_SEC_PKG_ERROR);
1685 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1688 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1689 pkt->auth_length = 0;
1690 pkt->call_id = call->pkt.call_id;
1691 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1692 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1693 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1694 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1695 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1696 pkt->u.alter_resp.secondary_address = "";
1697 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1698 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1699 pkt->u.alter_resp.auth_info = data_blob_null;
1701 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1702 if (!NT_STATUS_IS_OK(status)) {
1703 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1706 if (auth->auth_finished) {
1707 return dcesrv_auth_reply(call);
1710 subreq = gensec_update_send(call, call->event_ctx,
1711 auth->gensec_security,
1712 call->in_auth_info.credentials);
1713 if (subreq == NULL) {
1714 return NT_STATUS_NO_MEMORY;
1716 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1718 return dcesrv_conn_auth_wait_setup(conn);
1721 static void dcesrv_alter_done(struct tevent_req *subreq)
1723 struct dcesrv_call_state *call =
1724 tevent_req_callback_data(subreq,
1725 struct dcesrv_call_state);
1726 struct dcesrv_connection *conn = call->conn;
1729 status = gensec_update_recv(subreq, call,
1730 &call->out_auth_info->credentials);
1731 TALLOC_FREE(subreq);
1733 status = dcesrv_auth_complete(call, status);
1734 if (!NT_STATUS_IS_OK(status)) {
1735 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1736 dcesrv_conn_auth_wait_finished(conn, status);
1740 status = dcesrv_auth_reply(call);
1741 dcesrv_conn_auth_wait_finished(conn, status);
1746 possibly save the call for inspection with ndrdump
1748 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1752 const char *dump_dir;
1753 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1757 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1759 call->context->iface->name,
1760 call->pkt.u.request.opnum,
1762 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1763 DEBUG(0,("RPC SAVED %s\n", fname));
1769 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1771 TALLOC_CTX *frame = talloc_stackframe();
1772 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1773 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1774 const struct dcerpc_sec_vt_pcontext pcontext = {
1775 .abstract_syntax = call->context->iface->syntax_id,
1776 .transfer_syntax = call->context->transfer_syntax,
1778 const struct dcerpc_sec_vt_header2 header2 =
1779 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1780 enum ndr_err_code ndr_err;
1781 struct dcerpc_sec_verification_trailer *vt = NULL;
1782 NTSTATUS status = NT_STATUS_OK;
1785 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1787 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1789 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1790 status = ndr_map_error2ntstatus(ndr_err);
1794 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1795 &pcontext, &header2);
1797 status = NT_STATUS_ACCESS_DENIED;
1806 handle a dcerpc request packet
1808 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1810 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1811 enum dcerpc_transport_t transport =
1812 dcerpc_binding_get_transport(endpoint->ep_description);
1813 struct ndr_pull *pull;
1816 if (!call->conn->allow_request) {
1817 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1820 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1821 if (call->conn->auth_state.gensec_security &&
1822 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1823 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1826 if (call->context == NULL) {
1827 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1828 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1831 switch (call->conn->auth_state.auth_level) {
1832 case DCERPC_AUTH_LEVEL_NONE:
1833 case DCERPC_AUTH_LEVEL_PACKET:
1834 case DCERPC_AUTH_LEVEL_INTEGRITY:
1835 case DCERPC_AUTH_LEVEL_PRIVACY:
1838 if (!call->context->allow_connect) {
1841 addr = tsocket_address_string(call->conn->remote_address,
1844 DEBUG(2, ("%s: restrict auth_level_connect access "
1845 "to [%s] with auth[type=0x%x,level=0x%x] "
1846 "on [%s] from [%s]\n",
1847 __func__, call->context->iface->name,
1848 call->conn->auth_state.auth_type,
1849 call->conn->auth_state.auth_level,
1850 derpc_transport_string_by_transport(transport),
1852 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1857 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1860 addr = tsocket_address_string(call->conn->remote_address, call);
1862 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1863 "to [%s] with auth[type=0x%x,level=0x%x] "
1864 "on [%s] from [%s]\n",
1866 call->context->min_auth_level,
1867 call->context->iface->name,
1868 call->conn->auth_state.auth_type,
1869 call->conn->auth_state.auth_level,
1870 derpc_transport_string_by_transport(transport),
1872 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1875 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1876 NT_STATUS_HAVE_NO_MEMORY(pull);
1878 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1880 call->ndr_pull = pull;
1882 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1883 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1886 status = dcesrv_check_verification_trailer(call);
1887 if (!NT_STATUS_IS_OK(status)) {
1888 uint32_t faultcode = DCERPC_FAULT_OTHER;
1889 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1890 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1892 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1893 nt_errstr(status)));
1894 return dcesrv_fault(call, faultcode);
1897 /* unravel the NDR for the packet */
1898 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1899 if (!NT_STATUS_IS_OK(status)) {
1900 uint8_t extra_flags = 0;
1901 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1902 /* we got an unknown call */
1903 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1904 call->pkt.u.request.opnum,
1905 call->context->iface->name));
1906 dcesrv_save_call(call, "unknown");
1907 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1909 dcesrv_save_call(call, "pullfail");
1911 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1914 if (pull->offset != pull->data_size) {
1915 dcesrv_save_call(call, "extrabytes");
1916 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1917 pull->data_size - pull->offset));
1920 /* call the dispatch function */
1921 status = call->context->iface->dispatch(call, call, call->r);
1922 if (!NT_STATUS_IS_OK(status)) {
1923 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1924 call->context->iface->name,
1925 call->pkt.u.request.opnum,
1926 dcerpc_errstr(pull, call->fault_code)));
1927 return dcesrv_fault(call, call->fault_code);
1930 /* add the call to the pending list */
1931 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1933 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1934 return NT_STATUS_OK;
1937 return dcesrv_reply(call);
1942 remove the call from the right list when freed
1944 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1946 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1950 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1952 return conn->local_address;
1955 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1957 return conn->remote_address;
1961 process some input to a dcerpc endpoint server.
1963 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1964 struct ncacn_packet *pkt,
1968 struct dcesrv_call_state *call;
1969 struct dcesrv_call_state *existing = NULL;
1971 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1973 data_blob_free(&blob);
1975 return NT_STATUS_NO_MEMORY;
1977 call->conn = dce_conn;
1978 call->event_ctx = dce_conn->event_ctx;
1979 call->msg_ctx = dce_conn->msg_ctx;
1980 call->state_flags = call->conn->state_flags;
1981 call->time = timeval_current();
1982 call->list = DCESRV_LIST_NONE;
1984 talloc_steal(call, pkt);
1985 talloc_steal(call, blob.data);
1988 talloc_set_destructor(call, dcesrv_call_dequeue);
1990 if (call->conn->allow_bind) {
1992 * Only one bind is possible per connection
1994 call->conn->allow_bind = false;
1995 return dcesrv_bind(call);
1998 /* we have to check the signing here, before combining the
2000 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2001 if (!call->conn->allow_request) {
2002 return dcesrv_fault_disconnect(call,
2003 DCERPC_NCA_S_PROTO_ERROR);
2006 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2008 call->pkt.u.request.stub_and_verifier.length,
2009 0, /* required_flags */
2010 DCERPC_PFC_FLAG_FIRST |
2011 DCERPC_PFC_FLAG_LAST |
2012 DCERPC_PFC_FLAG_PENDING_CANCEL |
2013 0x08 | /* this is not defined, but should be ignored */
2014 DCERPC_PFC_FLAG_CONC_MPX |
2015 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2016 DCERPC_PFC_FLAG_MAYBE |
2017 DCERPC_PFC_FLAG_OBJECT_UUID);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 return dcesrv_fault_disconnect(call,
2020 DCERPC_NCA_S_PROTO_ERROR);
2023 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2025 * We don't use dcesrv_fault_disconnect()
2026 * here, because we don't want to set
2027 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2029 * Note that we don't check against the negotiated
2030 * max_recv_frag, but a hard coded value.
2032 dcesrv_call_disconnect_after(call,
2033 "dcesrv_auth_request - frag_length too large");
2034 return dcesrv_fault(call,
2035 DCERPC_NCA_S_PROTO_ERROR);
2038 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2039 if (dce_conn->pending_call_list != NULL) {
2041 * concurrent requests are only allowed
2042 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2044 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2045 dcesrv_call_disconnect_after(call,
2046 "dcesrv_auth_request - "
2047 "existing pending call without CONN_MPX");
2048 return dcesrv_fault(call,
2049 DCERPC_NCA_S_PROTO_ERROR);
2052 /* only one request is possible in the fragmented list */
2053 if (dce_conn->incoming_fragmented_call_list != NULL) {
2054 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2056 * Without DCERPC_PFC_FLAG_CONC_MPX
2057 * we need to return the FAULT on the
2058 * already existing call.
2060 * This is important to get the
2061 * call_id and context_id right.
2064 call = dce_conn->incoming_fragmented_call_list;
2066 dcesrv_call_disconnect_after(call,
2067 "dcesrv_auth_request - "
2068 "existing fragmented call");
2069 return dcesrv_fault(call,
2070 DCERPC_NCA_S_PROTO_ERROR);
2072 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2073 return dcesrv_fault_disconnect(call,
2074 DCERPC_FAULT_NO_CALL_ACTIVE);
2076 call->context = dcesrv_find_context(call->conn,
2077 call->pkt.u.request.context_id);
2078 if (call->context == NULL) {
2079 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2080 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2083 const struct dcerpc_request *nr = &call->pkt.u.request;
2084 const struct dcerpc_request *er = NULL;
2087 existing = dcesrv_find_fragmented_call(dce_conn,
2089 if (existing == NULL) {
2090 dcesrv_call_disconnect_after(call,
2091 "dcesrv_auth_request - "
2092 "no existing fragmented call");
2093 return dcesrv_fault(call,
2094 DCERPC_NCA_S_PROTO_ERROR);
2096 er = &existing->pkt.u.request;
2098 if (call->pkt.ptype != existing->pkt.ptype) {
2099 /* trying to play silly buggers are we? */
2100 return dcesrv_fault_disconnect(existing,
2101 DCERPC_NCA_S_PROTO_ERROR);
2103 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2106 return dcesrv_fault_disconnect(existing,
2107 DCERPC_NCA_S_PROTO_ERROR);
2109 if (nr->context_id != er->context_id) {
2110 return dcesrv_fault_disconnect(existing,
2111 DCERPC_NCA_S_PROTO_ERROR);
2113 if (nr->opnum != er->opnum) {
2114 return dcesrv_fault_disconnect(existing,
2115 DCERPC_NCA_S_PROTO_ERROR);
2120 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2122 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2124 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2125 payload_offset += 16;
2128 ok = dcesrv_auth_pkt_pull(call, &blob,
2129 0, /* required_flags */
2130 DCERPC_PFC_FLAG_FIRST |
2131 DCERPC_PFC_FLAG_LAST |
2132 DCERPC_PFC_FLAG_PENDING_CANCEL |
2133 0x08 | /* this is not defined, but should be ignored */
2134 DCERPC_PFC_FLAG_CONC_MPX |
2135 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2136 DCERPC_PFC_FLAG_MAYBE |
2137 DCERPC_PFC_FLAG_OBJECT_UUID,
2139 &call->pkt.u.request.stub_and_verifier);
2142 * We don't use dcesrv_fault_disconnect()
2143 * here, because we don't want to set
2144 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2146 dcesrv_call_disconnect_after(call,
2147 "dcesrv_auth_request - failed");
2148 if (call->fault_code == 0) {
2149 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2151 return dcesrv_fault(call, call->fault_code);
2155 /* see if this is a continued packet */
2156 if (existing != NULL) {
2157 struct dcerpc_request *er = &existing->pkt.u.request;
2158 const struct dcerpc_request *nr = &call->pkt.u.request;
2164 * Up to 4 MByte are allowed by all fragments
2166 available = dce_conn->max_total_request_size;
2167 if (er->stub_and_verifier.length > available) {
2168 dcesrv_call_disconnect_after(existing,
2169 "dcesrv_auth_request - existing payload too large");
2170 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2172 available -= er->stub_and_verifier.length;
2173 if (nr->alloc_hint > available) {
2174 dcesrv_call_disconnect_after(existing,
2175 "dcesrv_auth_request - alloc hint too large");
2176 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2178 if (nr->stub_and_verifier.length > available) {
2179 dcesrv_call_disconnect_after(existing,
2180 "dcesrv_auth_request - new payload too large");
2181 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2183 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2184 /* allocate at least 1 byte */
2185 alloc_hint = MAX(alloc_hint, 1);
2186 alloc_size = er->stub_and_verifier.length +
2187 nr->stub_and_verifier.length;
2188 alloc_size = MAX(alloc_size, alloc_hint);
2190 er->stub_and_verifier.data =
2191 talloc_realloc(existing,
2192 er->stub_and_verifier.data,
2193 uint8_t, alloc_size);
2194 if (er->stub_and_verifier.data == NULL) {
2196 return dcesrv_fault_with_flags(existing,
2197 DCERPC_FAULT_OUT_OF_RESOURCES,
2198 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2200 memcpy(er->stub_and_verifier.data +
2201 er->stub_and_verifier.length,
2202 nr->stub_and_verifier.data,
2203 nr->stub_and_verifier.length);
2204 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2206 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2212 /* this may not be the last pdu in the chain - if its isn't then
2213 just put it on the incoming_fragmented_call_list and wait for the rest */
2214 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2215 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2217 * Up to 4 MByte are allowed by all fragments
2219 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2220 dcesrv_call_disconnect_after(call,
2221 "dcesrv_auth_request - initial alloc hint too large");
2222 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2224 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2225 return NT_STATUS_OK;
2228 /* This removes any fragments we may have had stashed away */
2229 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2231 switch (call->pkt.ptype) {
2232 case DCERPC_PKT_BIND:
2233 status = dcesrv_bind_nak(call,
2234 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2236 case DCERPC_PKT_AUTH3:
2237 status = dcesrv_auth3(call);
2239 case DCERPC_PKT_ALTER:
2240 status = dcesrv_alter(call);
2242 case DCERPC_PKT_REQUEST:
2243 status = dcesrv_request(call);
2245 case DCERPC_PKT_CO_CANCEL:
2246 case DCERPC_PKT_ORPHANED:
2248 * Window just ignores CO_CANCEL and ORPHANED,
2251 status = NT_STATUS_OK;
2254 case DCERPC_PKT_BIND_ACK:
2255 case DCERPC_PKT_BIND_NAK:
2256 case DCERPC_PKT_ALTER_RESP:
2257 case DCERPC_PKT_RESPONSE:
2258 case DCERPC_PKT_FAULT:
2259 case DCERPC_PKT_SHUTDOWN:
2261 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2265 /* if we are going to be sending a reply then add
2266 it to the list of pending calls. We add it to the end to keep the call
2267 list in the order we will answer */
2268 if (!NT_STATUS_IS_OK(status)) {
2275 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2276 struct loadparm_context *lp_ctx,
2277 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2280 struct dcesrv_context *dce_ctx;
2283 if (!endpoint_servers) {
2284 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2285 return NT_STATUS_INTERNAL_ERROR;
2288 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2289 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2291 if (uid_wrapper_enabled()) {
2292 setenv("UID_WRAPPER_MYUID", "1", 1);
2294 dce_ctx->initial_euid = geteuid();
2295 if (uid_wrapper_enabled()) {
2296 unsetenv("UID_WRAPPER_MYUID");
2299 dce_ctx->endpoint_list = NULL;
2300 dce_ctx->lp_ctx = lp_ctx;
2301 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2302 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2303 dce_ctx->broken_connections = NULL;
2305 for (i=0;endpoint_servers[i];i++) {
2306 const struct dcesrv_endpoint_server *ep_server;
2308 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2310 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2311 return NT_STATUS_INTERNAL_ERROR;
2314 status = ep_server->init_server(dce_ctx, ep_server);
2315 if (!NT_STATUS_IS_OK(status)) {
2316 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2317 nt_errstr(status)));
2322 *_dce_ctx = dce_ctx;
2323 return NT_STATUS_OK;
2326 /* the list of currently registered DCERPC endpoint servers.
2328 static struct ep_server {
2329 struct dcesrv_endpoint_server *ep_server;
2330 } *ep_servers = NULL;
2331 static int num_ep_servers;
2334 register a DCERPC endpoint server.
2336 The 'name' can be later used by other backends to find the operations
2337 structure for this backend.
2340 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2343 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2344 /* its already registered! */
2345 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2347 return NT_STATUS_OBJECT_NAME_COLLISION;
2350 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2352 smb_panic("out of memory in dcerpc_register");
2355 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2356 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2360 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2363 return NT_STATUS_OK;
2367 return the operations structure for a named backend of the specified type
2369 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2373 for (i=0;i<num_ep_servers;i++) {
2374 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2375 return ep_servers[i].ep_server;
2382 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2384 static bool initialized;
2385 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2386 STATIC_dcerpc_server_MODULES_PROTO;
2387 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2388 init_module_fn *shared_init;
2395 shared_init = load_samba_modules(NULL, "dcerpc_server");
2397 run_init_functions(NULL, static_init);
2398 run_init_functions(NULL, shared_init);
2400 talloc_free(shared_init);
2404 return the DCERPC module version, and the size of some critical types
2405 This can be used by endpoint server modules to either detect compilation errors, or provide
2406 multiple implementations for different smbd compilation options in one module
2408 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2410 static const struct dcesrv_critical_sizes critical_sizes = {
2411 DCERPC_MODULE_VERSION,
2412 sizeof(struct dcesrv_context),
2413 sizeof(struct dcesrv_endpoint),
2414 sizeof(struct dcesrv_endpoint_server),
2415 sizeof(struct dcesrv_interface),
2416 sizeof(struct dcesrv_if_list),
2417 sizeof(struct dcesrv_connection),
2418 sizeof(struct dcesrv_call_state),
2419 sizeof(struct dcesrv_auth),
2420 sizeof(struct dcesrv_handle)
2423 return &critical_sizes;
2426 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2428 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2429 struct stream_connection *srv_conn;
2430 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2431 struct stream_connection);
2433 dce_conn->wait_send = NULL;
2434 dce_conn->wait_recv = NULL;
2435 dce_conn->wait_private = NULL;
2437 dce_conn->allow_bind = false;
2438 dce_conn->allow_auth3 = false;
2439 dce_conn->allow_alter = false;
2440 dce_conn->allow_request = false;
2442 if (dce_conn->pending_call_list == NULL) {
2443 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2445 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2446 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2450 if (dce_conn->terminate != NULL) {
2454 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2456 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2457 if (dce_conn->terminate == NULL) {
2458 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2460 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2463 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2465 struct dcesrv_connection *cur, *next;
2467 next = dce_ctx->broken_connections;
2468 while (next != NULL) {
2472 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2473 struct dcesrv_connection_context *context_cur, *context_next;
2475 context_next = cur->contexts;
2476 while (context_next != NULL) {
2477 context_cur = context_next;
2478 context_next = context_cur->next;
2480 dcesrv_connection_context_destructor(context_cur);
2484 dcesrv_terminate_connection(cur, cur->terminate);
2488 /* We need this include to be able to compile on some plateforms
2489 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2491 * It has to be that deep because otherwise we have a conflict on
2492 * const struct dcesrv_interface declaration.
2493 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2494 * which conflict with the bind used before.
2496 #include "system/network.h"
2498 struct dcesrv_sock_reply_state {
2499 struct dcesrv_connection *dce_conn;
2500 struct dcesrv_call_state *call;
2504 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2505 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2507 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2509 struct dcesrv_call_state *call;
2511 call = dce_conn->call_list;
2512 if (!call || !call->replies) {
2516 while (call->replies) {
2517 struct data_blob_list_item *rep = call->replies;
2518 struct dcesrv_sock_reply_state *substate;
2519 struct tevent_req *subreq;
2521 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2523 dcesrv_terminate_connection(dce_conn, "no memory");
2527 substate->dce_conn = dce_conn;
2528 substate->call = NULL;
2530 DLIST_REMOVE(call->replies, rep);
2532 if (call->replies == NULL && call->terminate_reason == NULL) {
2533 substate->call = call;
2536 substate->iov.iov_base = (void *) rep->blob.data;
2537 substate->iov.iov_len = rep->blob.length;
2539 subreq = tstream_writev_queue_send(substate,
2540 dce_conn->event_ctx,
2542 dce_conn->send_queue,
2545 dcesrv_terminate_connection(dce_conn, "no memory");
2548 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2552 if (call->terminate_reason != NULL) {
2553 struct tevent_req *subreq;
2555 subreq = tevent_queue_wait_send(call,
2556 dce_conn->event_ctx,
2557 dce_conn->send_queue);
2559 dcesrv_terminate_connection(dce_conn, __location__);
2562 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2566 DLIST_REMOVE(call->conn->call_list, call);
2567 call->list = DCESRV_LIST_NONE;
2570 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2572 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2573 struct dcesrv_sock_reply_state);
2577 struct dcesrv_call_state *call = substate->call;
2579 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2580 TALLOC_FREE(subreq);
2582 status = map_nt_error_from_unix_common(sys_errno);
2583 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2587 talloc_free(substate);
2593 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2595 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2597 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2598 struct dcesrv_call_state);
2602 /* make sure we stop send queue before removing subreq */
2603 tevent_queue_stop(call->conn->send_queue);
2605 ok = tevent_queue_wait_recv(subreq);
2606 TALLOC_FREE(subreq);
2608 dcesrv_terminate_connection(call->conn, __location__);
2612 /* disconnect after 200 usecs */
2613 tv = timeval_current_ofs_usec(200);
2614 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2615 if (subreq == NULL) {
2616 dcesrv_terminate_connection(call->conn, __location__);
2619 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2623 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2625 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2626 struct dcesrv_call_state);
2629 ok = tevent_wakeup_recv(subreq);
2630 TALLOC_FREE(subreq);
2632 dcesrv_terminate_connection(call->conn, __location__);
2636 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2639 struct dcesrv_socket_context {
2640 const struct dcesrv_endpoint *endpoint;
2641 struct dcesrv_context *dcesrv_ctx;
2645 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2647 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2650 struct dcesrv_socket_context *dcesrv_sock =
2651 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2652 enum dcerpc_transport_t transport =
2653 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2654 struct dcesrv_connection *dcesrv_conn = NULL;
2656 struct tevent_req *subreq;
2657 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2659 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2661 if (!srv_conn->session_info) {
2662 status = auth_anonymous_session_info(srv_conn,
2664 &srv_conn->session_info);
2665 if (!NT_STATUS_IS_OK(status)) {
2666 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2667 nt_errstr(status)));
2668 stream_terminate_connection(srv_conn, nt_errstr(status));
2674 * This fills in dcesrv_conn->endpoint with the endpoint
2675 * associated with the socket. From this point on we know
2676 * which (group of) services we are handling, but not the
2677 * specific interface.
2680 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2682 dcesrv_sock->endpoint,
2683 srv_conn->session_info,
2684 srv_conn->event.ctx,
2686 srv_conn->server_id,
2687 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2689 if (!NT_STATUS_IS_OK(status)) {
2690 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2691 nt_errstr(status)));
2692 stream_terminate_connection(srv_conn, nt_errstr(status));
2696 dcesrv_conn->transport.private_data = srv_conn;
2697 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2699 TALLOC_FREE(srv_conn->event.fde);
2701 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2702 if (!dcesrv_conn->send_queue) {
2703 status = NT_STATUS_NO_MEMORY;
2704 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2705 nt_errstr(status)));
2706 stream_terminate_connection(srv_conn, nt_errstr(status));
2710 if (transport == NCACN_NP) {
2711 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2712 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2713 &srv_conn->tstream);
2715 ret = tstream_bsd_existing_socket(dcesrv_conn,
2716 socket_get_fd(srv_conn->socket),
2717 &dcesrv_conn->stream);
2719 status = map_nt_error_from_unix_common(errno);
2720 DEBUG(0, ("dcesrv_sock_accept: "
2721 "failed to setup tstream: %s\n",
2722 nt_errstr(status)));
2723 stream_terminate_connection(srv_conn, nt_errstr(status));
2726 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2729 dcesrv_conn->local_address = srv_conn->local_address;
2730 dcesrv_conn->remote_address = srv_conn->remote_address;
2732 if (transport == NCALRPC) {
2737 sock_fd = socket_get_fd(srv_conn->socket);
2738 if (sock_fd == -1) {
2739 stream_terminate_connection(
2740 srv_conn, "socket_get_fd failed\n");
2744 ret = getpeereid(sock_fd, &uid, &gid);
2746 status = map_nt_error_from_unix_common(errno);
2747 DEBUG(0, ("dcesrv_sock_accept: "
2748 "getpeereid() failed for NCALRPC: %s\n",
2749 nt_errstr(status)));
2750 stream_terminate_connection(srv_conn, nt_errstr(status));
2753 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2754 struct tsocket_address *r = NULL;
2756 ret = tsocket_address_unix_from_path(dcesrv_conn,
2757 AS_SYSTEM_MAGIC_PATH_TOKEN,
2760 status = map_nt_error_from_unix_common(errno);
2761 DEBUG(0, ("dcesrv_sock_accept: "
2762 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2763 nt_errstr(status)));
2764 stream_terminate_connection(srv_conn, nt_errstr(status));
2767 dcesrv_conn->remote_address = r;
2771 srv_conn->private_data = dcesrv_conn;
2773 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2774 dcesrv_conn->event_ctx,
2775 dcesrv_conn->stream);
2777 status = NT_STATUS_NO_MEMORY;
2778 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2779 nt_errstr(status)));
2780 stream_terminate_connection(srv_conn, nt_errstr(status));
2783 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2788 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2790 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2792 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2793 struct dcesrv_connection);
2794 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2795 struct ncacn_packet *pkt;
2799 if (dce_conn->terminate) {
2801 * if the current connection is broken
2802 * we need to clean it up before any other connection
2804 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2805 dcesrv_cleanup_broken_connections(dce_ctx);
2809 dcesrv_cleanup_broken_connections(dce_ctx);
2811 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2813 TALLOC_FREE(subreq);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2819 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2820 if (!NT_STATUS_IS_OK(status)) {
2821 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2826 * This is used to block the connection during
2827 * pending authentication.
2829 if (dce_conn->wait_send != NULL) {
2830 subreq = dce_conn->wait_send(dce_conn,
2831 dce_conn->event_ctx,
2832 dce_conn->wait_private);
2834 status = NT_STATUS_NO_MEMORY;
2835 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2838 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2842 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2843 dce_conn->event_ctx,
2846 status = NT_STATUS_NO_MEMORY;
2847 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2850 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2853 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2855 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2856 struct dcesrv_connection);
2857 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2860 if (dce_conn->terminate) {
2862 * if the current connection is broken
2863 * we need to clean it up before any other connection
2865 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2866 dcesrv_cleanup_broken_connections(dce_ctx);
2870 dcesrv_cleanup_broken_connections(dce_ctx);
2872 status = dce_conn->wait_recv(subreq);
2873 dce_conn->wait_send = NULL;
2874 dce_conn->wait_recv = NULL;
2875 dce_conn->wait_private = NULL;
2876 TALLOC_FREE(subreq);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2882 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2883 dce_conn->event_ctx,
2886 status = NT_STATUS_NO_MEMORY;
2887 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2890 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2893 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2895 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2896 struct dcesrv_connection);
2897 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2900 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2902 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2903 struct dcesrv_connection);
2904 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2908 static const struct stream_server_ops dcesrv_stream_ops = {
2910 .accept_connection = dcesrv_sock_accept,
2911 .recv_handler = dcesrv_sock_recv,
2912 .send_handler = dcesrv_sock_send,
2915 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2916 struct loadparm_context *lp_ctx,
2917 struct dcesrv_endpoint *e,
2918 struct tevent_context *event_ctx,
2919 const struct model_ops *model_ops,
2920 void *process_context)
2922 struct dcesrv_socket_context *dcesrv_sock;
2925 const char *endpoint;
2927 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2928 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2930 /* remember the endpoint of this socket */
2931 dcesrv_sock->endpoint = e;
2932 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2934 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2936 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2937 model_ops, &dcesrv_stream_ops,
2938 "unix", endpoint, &port,
2939 lpcfg_socket_options(lp_ctx),
2940 dcesrv_sock, process_context);
2941 if (!NT_STATUS_IS_OK(status)) {
2942 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2943 endpoint, nt_errstr(status)));
2949 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2950 struct loadparm_context *lp_ctx,
2951 struct dcesrv_endpoint *e,
2952 struct tevent_context *event_ctx,
2953 const struct model_ops *model_ops,
2954 void *process_context)
2956 struct dcesrv_socket_context *dcesrv_sock;
2960 const char *endpoint;
2962 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2964 if (endpoint == NULL) {
2966 * No identifier specified: use DEFAULT.
2968 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2969 * no endpoint and let the epmapper worry about it.
2971 endpoint = "DEFAULT";
2972 status = dcerpc_binding_set_string_option(e->ep_description,
2975 if (!NT_STATUS_IS_OK(status)) {
2976 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2977 nt_errstr(status)));
2982 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2985 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2986 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2988 /* remember the endpoint of this socket */
2989 dcesrv_sock->endpoint = e;
2990 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2992 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2993 model_ops, &dcesrv_stream_ops,
2994 "unix", full_path, &port,
2995 lpcfg_socket_options(lp_ctx),
2996 dcesrv_sock, process_context);
2997 if (!NT_STATUS_IS_OK(status)) {
2998 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2999 endpoint, full_path, nt_errstr(status)));
3004 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3005 struct loadparm_context *lp_ctx,
3006 struct dcesrv_endpoint *e,
3007 struct tevent_context *event_ctx,
3008 const struct model_ops *model_ops,
3009 void *process_context)
3011 struct dcesrv_socket_context *dcesrv_sock;
3013 const char *endpoint;
3015 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3016 if (endpoint == NULL) {
3017 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3018 return NT_STATUS_INVALID_PARAMETER;
3021 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3022 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3024 /* remember the endpoint of this socket */
3025 dcesrv_sock->endpoint = e;
3026 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3028 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3029 model_ops, &dcesrv_stream_ops,
3031 dcesrv_sock, process_context);
3032 if (!NT_STATUS_IS_OK(status)) {
3033 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3034 endpoint, nt_errstr(status)));
3038 return NT_STATUS_OK;
3042 add a socket address to the list of events, one event per dcerpc endpoint
3044 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3045 struct dcesrv_endpoint *e,
3046 struct tevent_context *event_ctx,
3047 const struct model_ops *model_ops,
3048 const char *address,
3049 void *process_context)
3051 struct dcesrv_socket_context *dcesrv_sock;
3054 const char *endpoint;
3057 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3058 if (endpoint != NULL) {
3059 port = atoi(endpoint);
3062 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3063 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3065 /* remember the endpoint of this socket */
3066 dcesrv_sock->endpoint = e;
3067 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3069 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3070 model_ops, &dcesrv_stream_ops,
3071 "ip", address, &port,
3072 lpcfg_socket_options(dce_ctx->lp_ctx),
3073 dcesrv_sock, process_context);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 struct dcesrv_if_list *iface;
3076 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3078 for (iface = e->interface_list; iface; iface = iface->next) {
3079 DEBUGADD(0, ("%s ", iface->iface.name));
3081 DEBUGADD(0, ("failed - %s",
3082 nt_errstr(status)));
3086 snprintf(port_str, sizeof(port_str), "%u", port);
3088 status = dcerpc_binding_set_string_option(e->ep_description,
3089 "endpoint", port_str);
3090 if (!NT_STATUS_IS_OK(status)) {
3091 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3092 port_str, nt_errstr(status)));
3095 struct dcesrv_if_list *iface;
3096 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3097 address, port_str));
3098 for (iface = e->interface_list; iface; iface = iface->next) {
3099 DEBUGADD(4, ("%s ", iface->iface.name));
3101 DEBUGADD(4, ("\n"));
3104 return NT_STATUS_OK;
3107 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3109 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3110 struct loadparm_context *lp_ctx,
3111 struct dcesrv_endpoint *e,
3112 struct tevent_context *event_ctx,
3113 const struct model_ops *model_ops,
3114 void *process_context)
3118 /* Add TCP/IP sockets */
3119 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3122 struct interface *ifaces;
3124 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3126 num_interfaces = iface_list_count(ifaces);
3127 for(i = 0; i < num_interfaces; i++) {
3128 const char *address = iface_list_n_ip(ifaces, i);
3129 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3132 NT_STATUS_NOT_OK_RETURN(status);
3137 size_t num_binds = 0;
3138 wcard = iface_list_wildcard(dce_ctx);
3139 NT_STATUS_HAVE_NO_MEMORY(wcard);
3140 for (i=0; wcard[i]; i++) {
3141 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3142 model_ops, wcard[i],
3144 if (NT_STATUS_IS_OK(status)) {
3149 if (num_binds == 0) {
3150 return NT_STATUS_INVALID_PARAMETER_MIX;
3154 return NT_STATUS_OK;
3157 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3158 struct loadparm_context *lp_ctx,
3159 struct dcesrv_endpoint *e,
3160 struct tevent_context *event_ctx,
3161 const struct model_ops *model_ops,
3162 void *process_context)
3164 enum dcerpc_transport_t transport =
3165 dcerpc_binding_get_transport(e->ep_description);
3167 switch (transport) {
3168 case NCACN_UNIX_STREAM:
3169 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3170 model_ops, process_context);
3173 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3174 model_ops, process_context);
3177 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3178 model_ops, process_context);
3181 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3182 model_ops, process_context);
3185 return NT_STATUS_NOT_SUPPORTED;
3191 * retrieve credentials from a dce_call
3193 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3195 return dce_call->conn->auth_state.session_info->credentials;
3199 * returns true if this is an authenticated call
3201 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3203 enum security_user_level level;
3204 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3205 return level >= SECURITY_USER;
3209 * retrieve account_name for a dce_call
3211 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3213 return dce_call->context->conn->auth_state.session_info->info->account_name;
3217 * retrieve session_info from a dce_call
3219 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3221 return dce_call->context->conn->auth_state.session_info;