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 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
483 return NT_STATUS_NO_USER_SESSION_KEY;
486 return dcesrv_session_info_session_key(auth, session_key);
490 * Fetch the authentication session key if available.
492 * This is the key generated by a gensec authentication.
495 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
496 DATA_BLOB *session_key)
498 struct dcesrv_auth *auth = &call->conn->auth_state;
500 return dcesrv_session_info_session_key(auth, session_key);
504 fetch the user session key - may be default (above) or the SMB session key
506 The key is always truncated to 16 bytes
508 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
509 DATA_BLOB *session_key)
511 struct dcesrv_auth *auth = &p->auth_state;
514 if (auth->session_key == NULL) {
515 return NT_STATUS_NO_USER_SESSION_KEY;
518 status = auth->session_key(p, session_key);
519 if (!NT_STATUS_IS_OK(status)) {
523 session_key->length = MIN(session_key->length, 16);
529 * Fetch the transport session key if available.
530 * Typically this is the SMB session key
531 * or a fixed key for local transports.
533 * The key is always truncated to 16 bytes.
535 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
536 DATA_BLOB *session_key)
538 return dcesrv_fetch_session_key(call->conn, session_key);
542 connect to a dcerpc endpoint
544 static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
546 const struct dcesrv_endpoint *ep,
547 struct auth_session_info *session_info,
548 struct tevent_context *event_ctx,
549 struct imessaging_context *msg_ctx,
550 struct server_id server_id,
551 uint32_t state_flags,
552 struct dcesrv_connection **_p)
554 enum dcerpc_transport_t transport =
555 dcerpc_binding_get_transport(ep->ep_description);
556 struct dcesrv_connection *p;
559 return NT_STATUS_ACCESS_DENIED;
562 p = talloc_zero(mem_ctx, struct dcesrv_connection);
563 NT_STATUS_HAVE_NO_MEMORY(p);
565 if (!talloc_reference(p, session_info)) {
567 return NT_STATUS_NO_MEMORY;
570 p->dce_ctx = dce_ctx;
572 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
573 p->event_ctx = event_ctx;
574 p->msg_ctx = msg_ctx;
575 p->server_id = server_id;
576 p->state_flags = state_flags;
577 p->allow_bind = true;
578 p->max_recv_frag = 5840;
579 p->max_xmit_frag = 5840;
580 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
582 p->auth_state.session_info = session_info;
585 p->auth_state.session_key = dcesrv_inherited_session_key;
588 case NCACN_UNIX_STREAM:
589 p->auth_state.session_key = dcesrv_generic_session_key;
593 * All other's get a NULL pointer, which
594 * results in NT_STATUS_NO_USER_SESSION_KEY
600 * For now we only support NDR32.
602 p->preferred_transfer = &ndr_transfer_syntax_ndr;
609 move a call from an existing linked list to the specified list. This
610 prevents bugs where we forget to remove the call from a previous
613 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
614 enum dcesrv_call_list list)
616 switch (call->list) {
617 case DCESRV_LIST_NONE:
619 case DCESRV_LIST_CALL_LIST:
620 DLIST_REMOVE(call->conn->call_list, call);
622 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
623 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
625 case DCESRV_LIST_PENDING_CALL_LIST:
626 DLIST_REMOVE(call->conn->pending_call_list, call);
631 case DCESRV_LIST_NONE:
633 case DCESRV_LIST_CALL_LIST:
634 DLIST_ADD_END(call->conn->call_list, call);
636 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
637 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
639 case DCESRV_LIST_PENDING_CALL_LIST:
640 DLIST_ADD_END(call->conn->pending_call_list, call);
645 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
648 if (call->conn->terminate != NULL) {
652 call->conn->allow_bind = false;
653 call->conn->allow_alter = false;
654 call->conn->allow_auth3 = false;
655 call->conn->allow_request = false;
657 call->terminate_reason = talloc_strdup(call, reason);
658 if (call->terminate_reason == NULL) {
659 call->terminate_reason = __location__;
664 return a dcerpc bind_nak
666 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
668 struct ncacn_packet pkt;
669 struct dcerpc_bind_nak_version version;
670 struct data_blob_list_item *rep;
672 static const uint8_t _pad[3] = { 0, };
675 * We add the call to the pending_call_list
676 * in order to defer the termination.
678 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
680 /* setup a bind_nak */
681 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
683 pkt.call_id = call->pkt.call_id;
684 pkt.ptype = DCERPC_PKT_BIND_NAK;
685 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
686 pkt.u.bind_nak.reject_reason = reason;
687 version.rpc_vers = 5;
688 version.rpc_vers_minor = 0;
689 pkt.u.bind_nak.num_versions = 1;
690 pkt.u.bind_nak.versions = &version;
691 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
693 rep = talloc_zero(call, struct data_blob_list_item);
695 return NT_STATUS_NO_MEMORY;
698 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
699 if (!NT_STATUS_IS_OK(status)) {
703 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
705 DLIST_ADD_END(call->replies, rep);
706 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
708 if (call->conn->call_list && call->conn->call_list->replies) {
709 if (call->conn->transport.report_output_data) {
710 call->conn->transport.report_output_data(call->conn);
717 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
721 * We add the call to the pending_call_list
722 * in order to defer the termination.
724 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
726 return dcesrv_fault_with_flags(call, fault_code,
727 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
730 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
732 DLIST_REMOVE(c->conn->contexts, c);
734 if (c->iface && c->iface->unbind) {
735 c->iface->unbind(c, c->iface);
742 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
744 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
745 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
746 enum dcerpc_transport_t transport =
747 dcerpc_binding_get_transport(endpoint->ep_description);
748 struct dcesrv_connection_context *context = dce_call->context;
749 const struct dcesrv_interface *iface = context->iface;
751 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
753 if (transport == NCALRPC) {
754 context->allow_connect = true;
759 * allow overwrite per interface
760 * allow dcerpc auth level connect:<interface>
762 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
763 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
764 "allow dcerpc auth level connect",
766 context->allow_connect);
769 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
770 const struct dcesrv_interface *iface)
772 if (dce_call->context == NULL) {
773 return NT_STATUS_INTERNAL_ERROR;
777 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
778 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
780 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
784 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
785 const struct dcesrv_interface *iface)
787 if (dce_call->context == NULL) {
788 return NT_STATUS_INTERNAL_ERROR;
791 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
795 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
796 const struct dcesrv_interface *iface)
798 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
799 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
800 enum dcerpc_transport_t transport =
801 dcerpc_binding_get_transport(endpoint->ep_description);
802 struct dcesrv_connection_context *context = dce_call->context;
804 if (context == NULL) {
805 return NT_STATUS_INTERNAL_ERROR;
808 if (transport == NCALRPC) {
809 context->allow_connect = true;
814 * allow overwrite per interface
815 * allow dcerpc auth level connect:<interface>
817 context->allow_connect = false;
818 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
819 "allow dcerpc auth level connect",
821 context->allow_connect);
825 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
826 const struct dcesrv_interface *iface)
828 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
829 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
830 enum dcerpc_transport_t transport =
831 dcerpc_binding_get_transport(endpoint->ep_description);
832 struct dcesrv_connection_context *context = dce_call->context;
834 if (context == NULL) {
835 return NT_STATUS_INTERNAL_ERROR;
838 if (transport == NCALRPC) {
839 context->allow_connect = true;
844 * allow overwrite per interface
845 * allow dcerpc auth level connect:<interface>
847 context->allow_connect = true;
848 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
849 "allow dcerpc auth level connect",
851 context->allow_connect);
855 struct dcesrv_conn_auth_wait_context {
856 struct tevent_req *req;
861 struct dcesrv_conn_auth_wait_state {
865 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
866 struct tevent_context *ev,
869 struct dcesrv_conn_auth_wait_context *auth_wait =
870 talloc_get_type_abort(private_data,
871 struct dcesrv_conn_auth_wait_context);
872 struct tevent_req *req = NULL;
873 struct dcesrv_conn_auth_wait_state *state = NULL;
875 req = tevent_req_create(mem_ctx, &state,
876 struct dcesrv_conn_auth_wait_state);
880 auth_wait->req = req;
882 tevent_req_defer_callback(req, ev);
884 if (!auth_wait->done) {
888 if (tevent_req_nterror(req, auth_wait->status)) {
889 return tevent_req_post(req, ev);
892 tevent_req_done(req);
893 return tevent_req_post(req, ev);
896 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
898 return tevent_req_simple_recv_ntstatus(req);
901 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
903 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
905 if (conn->wait_send != NULL) {
906 return NT_STATUS_INTERNAL_ERROR;
909 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
910 if (auth_wait == NULL) {
911 return NT_STATUS_NO_MEMORY;
914 conn->wait_private = auth_wait;
915 conn->wait_send = dcesrv_conn_auth_wait_send;
916 conn->wait_recv = dcesrv_conn_auth_wait_recv;
920 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
923 struct dcesrv_conn_auth_wait_context *auth_wait =
924 talloc_get_type_abort(conn->wait_private,
925 struct dcesrv_conn_auth_wait_context);
927 auth_wait->done = true;
928 auth_wait->status = status;
930 if (auth_wait->req == NULL) {
934 if (tevent_req_nterror(auth_wait->req, status)) {
938 tevent_req_done(auth_wait->req);
941 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
943 static void dcesrv_bind_done(struct tevent_req *subreq);
946 handle a bind request
948 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
950 struct dcesrv_connection *conn = call->conn;
951 struct ncacn_packet *pkt = &call->ack_pkt;
953 uint32_t extra_flags = 0;
954 uint16_t max_req = 0;
955 uint16_t max_rep = 0;
956 const char *ep_prefix = "";
957 const char *endpoint = NULL;
958 struct dcesrv_auth *auth = &call->conn->auth_state;
959 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
960 struct dcerpc_ack_ctx *ack_features = NULL;
961 struct tevent_req *subreq = NULL;
964 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
966 call->pkt.u.bind.auth_info.length,
967 0, /* required flags */
968 DCERPC_PFC_FLAG_FIRST |
969 DCERPC_PFC_FLAG_LAST |
970 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
971 0x08 | /* this is not defined, but should be ignored */
972 DCERPC_PFC_FLAG_CONC_MPX |
973 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
974 DCERPC_PFC_FLAG_MAYBE |
975 DCERPC_PFC_FLAG_OBJECT_UUID);
976 if (!NT_STATUS_IS_OK(status)) {
977 return dcesrv_bind_nak(call,
978 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
981 /* max_recv_frag and max_xmit_frag result always in the same value! */
982 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
983 call->pkt.u.bind.max_recv_frag);
985 * The values are between 2048 and 5840 tested against Windows 2012R2
986 * via ncacn_ip_tcp on port 135.
988 max_req = MAX(2048, max_req);
989 max_rep = MIN(max_req, call->conn->max_recv_frag);
990 /* They are truncated to an 8 byte boundary. */
993 /* max_recv_frag and max_xmit_frag result always in the same value! */
994 call->conn->max_recv_frag = max_rep;
995 call->conn->max_xmit_frag = max_rep;
998 if provided, check the assoc_group is valid
1000 if (call->pkt.u.bind.assoc_group_id != 0) {
1001 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
1002 call->conn->dce_ctx,
1003 call->pkt.u.bind.assoc_group_id);
1005 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
1006 call->conn->dce_ctx);
1010 * The NETLOGON server does not use handles and so
1011 * there is no need to support association groups, but
1012 * we need to give back a number regardless.
1014 * We have to do this when it is not run as a single process,
1015 * because then it can't see the other valid association
1016 * groups. We handle this genericly for all endpoints not
1017 * running in single process mode.
1019 * We know which endpoint we are on even before checking the
1020 * iface UUID, so for simplicity we enforce the same policy
1021 * for all interfaces on the endpoint.
1023 * This means that where NETLOGON
1024 * shares an endpoint (such as ncalrpc or of 'lsa over
1025 * netlogon' is set) we will still check association groups.
1029 if (call->conn->assoc_group == NULL &&
1030 !call->conn->endpoint->use_single_process) {
1031 call->conn->assoc_group
1032 = dcesrv_assoc_group_new(call->conn,
1033 call->conn->dce_ctx);
1035 if (call->conn->assoc_group == NULL) {
1036 return dcesrv_bind_nak(call, 0);
1039 if (call->pkt.u.bind.num_contexts < 1) {
1040 return dcesrv_bind_nak(call, 0);
1043 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1044 call->pkt.u.bind.num_contexts);
1045 if (ack_ctx_list == NULL) {
1046 return dcesrv_bind_nak(call, 0);
1050 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1051 * dcesrv_check_or_create_context()) and do some protocol validation
1052 * and set sane defaults.
1054 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1055 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1056 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1057 bool is_feature = false;
1058 uint64_t features = 0;
1060 if (c->num_transfer_syntaxes == 0) {
1061 return dcesrv_bind_nak(call, 0);
1064 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1065 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1068 * It's only treated as bind time feature request, if the first
1069 * transfer_syntax matches, all others are ignored.
1071 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1077 if (ack_features != NULL) {
1079 * Only one bind time feature context is allowed.
1081 return dcesrv_bind_nak(call, 0);
1085 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1086 a->reason.negotiate = 0;
1087 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1088 /* not supported yet */
1090 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1091 a->reason.negotiate |=
1092 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1095 call->conn->bind_time_features = a->reason.negotiate;
1099 * Try to negotiate one new presentation context.
1101 * Deep in here we locate the iface (by uuid) that the client
1102 * requested, from the list of interfaces on the
1103 * call->conn->endpoint, and call iface->bind() on that iface.
1105 * call->conn was set up at the accept() of the socket, and
1106 * call->conn->endpoint has a list of interfaces restricted to
1107 * this port or pipe.
1109 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1110 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1111 return dcesrv_bind_nak(call, 0);
1113 if (!NT_STATUS_IS_OK(status)) {
1118 * At this point we still don't know which interface (eg
1119 * netlogon, lsa, drsuapi) the caller requested in this bind!
1120 * The most recently added context is available as the first
1121 * element in the linked list at call->conn->contexts, that is
1122 * call->conn->contexts->iface, but they may not have
1123 * requested one at all!
1126 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1127 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1128 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1129 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1132 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1133 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1137 * After finding the interface and setting up the NDR
1138 * transport negotiation etc, handle any authentication that
1139 * is being requested.
1141 if (!dcesrv_auth_bind(call)) {
1143 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1145 * With DCERPC_AUTH_LEVEL_NONE, we get the
1146 * reject_reason in auth->auth_context_id.
1148 return dcesrv_bind_nak(call, auth->auth_context_id);
1152 * This must a be a temporary failure e.g. talloc or invalid
1153 * configuration, e.g. no machine account.
1155 return dcesrv_bind_nak(call,
1156 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1159 /* setup a bind_ack */
1160 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1161 pkt->auth_length = 0;
1162 pkt->call_id = call->pkt.call_id;
1163 pkt->ptype = DCERPC_PKT_BIND_ACK;
1164 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1165 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1166 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1167 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1169 endpoint = dcerpc_binding_get_string_option(
1170 call->conn->endpoint->ep_description,
1172 if (endpoint == NULL) {
1176 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1178 * TODO: check if this is really needed
1180 * Or if we should fix this in our idl files.
1182 ep_prefix = "\\PIPE\\";
1186 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1189 if (pkt->u.bind_ack.secondary_address == NULL) {
1190 return NT_STATUS_NO_MEMORY;
1192 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1193 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1194 pkt->u.bind_ack.auth_info = data_blob_null;
1196 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1197 if (!NT_STATUS_IS_OK(status)) {
1198 return dcesrv_bind_nak(call, 0);
1201 if (auth->auth_finished) {
1202 return dcesrv_auth_reply(call);
1205 subreq = gensec_update_send(call, call->event_ctx,
1206 auth->gensec_security,
1207 call->in_auth_info.credentials);
1208 if (subreq == NULL) {
1209 return NT_STATUS_NO_MEMORY;
1211 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1213 return dcesrv_conn_auth_wait_setup(conn);
1216 static void dcesrv_bind_done(struct tevent_req *subreq)
1218 struct dcesrv_call_state *call =
1219 tevent_req_callback_data(subreq,
1220 struct dcesrv_call_state);
1221 struct dcesrv_connection *conn = call->conn;
1224 status = gensec_update_recv(subreq, call,
1225 &call->out_auth_info->credentials);
1226 TALLOC_FREE(subreq);
1228 status = dcesrv_auth_complete(call, status);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 status = dcesrv_bind_nak(call, 0);
1231 dcesrv_conn_auth_wait_finished(conn, status);
1235 status = dcesrv_auth_reply(call);
1236 dcesrv_conn_auth_wait_finished(conn, status);
1240 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1242 struct ncacn_packet *pkt = &call->ack_pkt;
1243 struct data_blob_list_item *rep = NULL;
1246 rep = talloc_zero(call, struct data_blob_list_item);
1248 return NT_STATUS_NO_MEMORY;
1251 status = ncacn_push_auth(&rep->blob, call, pkt,
1252 call->out_auth_info);
1253 if (!NT_STATUS_IS_OK(status)) {
1257 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1259 DLIST_ADD_END(call->replies, rep);
1260 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1262 if (call->conn->call_list && call->conn->call_list->replies) {
1263 if (call->conn->transport.report_output_data) {
1264 call->conn->transport.report_output_data(call->conn);
1268 return NT_STATUS_OK;
1272 static void dcesrv_auth3_done(struct tevent_req *subreq);
1275 handle a auth3 request
1277 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1279 struct dcesrv_connection *conn = call->conn;
1280 struct dcesrv_auth *auth = &call->conn->auth_state;
1281 struct tevent_req *subreq = NULL;
1284 if (!call->conn->allow_auth3) {
1285 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1288 if (call->conn->auth_state.auth_finished) {
1289 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1292 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1294 call->pkt.u.auth3.auth_info.length,
1295 0, /* required flags */
1296 DCERPC_PFC_FLAG_FIRST |
1297 DCERPC_PFC_FLAG_LAST |
1298 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1299 0x08 | /* this is not defined, but should be ignored */
1300 DCERPC_PFC_FLAG_CONC_MPX |
1301 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1302 DCERPC_PFC_FLAG_MAYBE |
1303 DCERPC_PFC_FLAG_OBJECT_UUID);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1308 /* handle the auth3 in the auth code */
1309 if (!dcesrv_auth_prepare_auth3(call)) {
1311 * we don't send a reply to a auth3 request,
1312 * except by a fault.
1314 * In anycase we mark the connection as
1317 call->conn->auth_state.auth_invalid = true;
1318 if (call->fault_code != 0) {
1319 return dcesrv_fault_disconnect(call, call->fault_code);
1322 return NT_STATUS_OK;
1325 subreq = gensec_update_send(call, call->event_ctx,
1326 auth->gensec_security,
1327 call->in_auth_info.credentials);
1328 if (subreq == NULL) {
1329 return NT_STATUS_NO_MEMORY;
1331 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1333 return dcesrv_conn_auth_wait_setup(conn);
1336 static void dcesrv_auth3_done(struct tevent_req *subreq)
1338 struct dcesrv_call_state *call =
1339 tevent_req_callback_data(subreq,
1340 struct dcesrv_call_state);
1341 struct dcesrv_connection *conn = call->conn;
1344 status = gensec_update_recv(subreq, call,
1345 &call->out_auth_info->credentials);
1346 TALLOC_FREE(subreq);
1348 status = dcesrv_auth_complete(call, status);
1349 if (!NT_STATUS_IS_OK(status)) {
1351 * we don't send a reply to a auth3 request,
1352 * except by a fault.
1354 * In anycase we mark the connection as
1357 call->conn->auth_state.auth_invalid = true;
1358 if (call->fault_code != 0) {
1359 status = dcesrv_fault_disconnect(call, call->fault_code);
1360 dcesrv_conn_auth_wait_finished(conn, status);
1364 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1369 * we don't send a reply to a auth3 request.
1372 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1377 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1378 const struct dcerpc_bind *b,
1379 const struct dcerpc_ctx_list *ctx,
1380 struct dcerpc_ack_ctx *ack,
1382 const struct ndr_syntax_id *supported_transfer)
1384 uint32_t if_version;
1385 struct dcesrv_connection_context *context;
1386 const struct dcesrv_interface *iface;
1389 const struct ndr_syntax_id *selected_transfer = NULL;
1394 return NT_STATUS_INTERNAL_ERROR;
1397 return NT_STATUS_INTERNAL_ERROR;
1399 if (ctx->num_transfer_syntaxes < 1) {
1400 return NT_STATUS_INTERNAL_ERROR;
1403 return NT_STATUS_INTERNAL_ERROR;
1405 if (supported_transfer == NULL) {
1406 return NT_STATUS_INTERNAL_ERROR;
1409 switch (ack->result) {
1410 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1411 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1413 * We is already completed.
1415 return NT_STATUS_OK;
1420 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1421 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1423 if_version = ctx->abstract_syntax.if_version;
1424 uuid = ctx->abstract_syntax.uuid;
1426 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1427 if (iface == NULL) {
1428 char *uuid_str = GUID_string(call, &uuid);
1429 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1430 talloc_free(uuid_str);
1432 * We report this only via ack->result
1434 return NT_STATUS_OK;
1437 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1438 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1440 if (validate_only) {
1442 * We report this only via ack->result
1444 return NT_STATUS_OK;
1447 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1449 * we only do NDR encoded dcerpc for now.
1451 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1452 supported_transfer);
1454 selected_transfer = supported_transfer;
1459 context = dcesrv_find_context(call->conn, ctx->context_id);
1460 if (context != NULL) {
1461 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1462 &ctx->abstract_syntax);
1464 return NT_STATUS_RPC_PROTOCOL_ERROR;
1467 if (selected_transfer != NULL) {
1468 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1471 return NT_STATUS_RPC_PROTOCOL_ERROR;
1474 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1475 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1476 ack->syntax = context->transfer_syntax;
1480 * We report this only via ack->result
1482 return NT_STATUS_OK;
1485 if (selected_transfer == NULL) {
1487 * We report this only via ack->result
1489 return NT_STATUS_OK;
1492 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1493 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1495 /* add this context to the list of available context_ids */
1496 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1497 if (context == NULL) {
1498 return NT_STATUS_NO_MEMORY;
1500 context->conn = call->conn;
1501 context->context_id = ctx->context_id;
1502 context->iface = iface;
1503 context->transfer_syntax = *selected_transfer;
1504 context->private_data = NULL;
1505 DLIST_ADD(call->conn->contexts, context);
1506 call->context = context;
1507 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1509 dcesrv_prepare_context_auth(call);
1512 * Multiplex is supported by default
1514 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1516 status = iface->bind(call, iface, if_version);
1517 call->context = NULL;
1518 if (!NT_STATUS_IS_OK(status)) {
1519 /* we don't want to trigger the iface->unbind() hook */
1520 context->iface = NULL;
1521 talloc_free(context);
1523 * We report this only via ack->result
1525 return NT_STATUS_OK;
1528 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1529 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1530 ack->syntax = context->transfer_syntax;
1531 return NT_STATUS_OK;
1534 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1535 const struct dcerpc_bind *b,
1536 struct dcerpc_ack_ctx *ack_ctx_list)
1540 bool validate_only = false;
1541 bool preferred_ndr32;
1544 * Try to negotiate one new presentation context,
1545 * using our preferred transfer syntax.
1547 for (i = 0; i < b->num_contexts; i++) {
1548 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1549 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1551 status = dcesrv_check_or_create_context(call, b, c, a,
1553 call->conn->preferred_transfer);
1554 if (!NT_STATUS_IS_OK(status)) {
1558 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1560 * We managed to negotiate one context.
1564 validate_only = true;
1568 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1569 call->conn->preferred_transfer);
1570 if (preferred_ndr32) {
1574 return NT_STATUS_OK;
1578 * Try to negotiate one new presentation context,
1579 * using NDR 32 as fallback.
1581 for (i = 0; i < b->num_contexts; i++) {
1582 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1583 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1585 status = dcesrv_check_or_create_context(call, b, c, a,
1587 &ndr_transfer_syntax_ndr);
1588 if (!NT_STATUS_IS_OK(status)) {
1592 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1594 * We managed to negotiate one context.
1598 validate_only = true;
1602 return NT_STATUS_OK;
1605 static void dcesrv_alter_done(struct tevent_req *subreq);
1608 handle a alter context request
1610 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1612 struct dcesrv_connection *conn = call->conn;
1614 bool auth_ok = false;
1615 struct ncacn_packet *pkt = &call->ack_pkt;
1616 uint32_t extra_flags = 0;
1617 struct dcesrv_auth *auth = &call->conn->auth_state;
1618 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1619 struct tevent_req *subreq = NULL;
1622 if (!call->conn->allow_alter) {
1623 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1626 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1628 call->pkt.u.alter.auth_info.length,
1629 0, /* required flags */
1630 DCERPC_PFC_FLAG_FIRST |
1631 DCERPC_PFC_FLAG_LAST |
1632 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1633 0x08 | /* this is not defined, but should be ignored */
1634 DCERPC_PFC_FLAG_CONC_MPX |
1635 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1636 DCERPC_PFC_FLAG_MAYBE |
1637 DCERPC_PFC_FLAG_OBJECT_UUID);
1638 if (!NT_STATUS_IS_OK(status)) {
1639 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1642 auth_ok = dcesrv_auth_alter(call);
1644 if (call->fault_code != 0) {
1645 return dcesrv_fault_disconnect(call, call->fault_code);
1649 if (call->pkt.u.alter.num_contexts < 1) {
1650 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1653 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1654 call->pkt.u.alter.num_contexts);
1655 if (ack_ctx_list == NULL) {
1656 return NT_STATUS_NO_MEMORY;
1660 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1661 * dcesrv_check_or_create_context()) and do some protocol validation
1662 * and set sane defaults.
1664 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1665 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1666 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1668 if (c->num_transfer_syntaxes == 0) {
1669 return dcesrv_fault_disconnect(call,
1670 DCERPC_NCA_S_PROTO_ERROR);
1673 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1674 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1678 * Try to negotiate one new presentation context.
1680 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1681 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1682 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1684 if (!NT_STATUS_IS_OK(status)) {
1688 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1689 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1690 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1691 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1694 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1695 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1698 /* handle any authentication that is being requested */
1700 if (call->in_auth_info.auth_type !=
1701 call->conn->auth_state.auth_type)
1703 return dcesrv_fault_disconnect(call,
1704 DCERPC_FAULT_SEC_PKG_ERROR);
1706 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1709 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1710 pkt->auth_length = 0;
1711 pkt->call_id = call->pkt.call_id;
1712 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1713 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1714 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1715 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1716 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1717 pkt->u.alter_resp.secondary_address = "";
1718 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1719 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1720 pkt->u.alter_resp.auth_info = data_blob_null;
1722 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1723 if (!NT_STATUS_IS_OK(status)) {
1724 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1727 if (auth->auth_finished) {
1728 return dcesrv_auth_reply(call);
1731 subreq = gensec_update_send(call, call->event_ctx,
1732 auth->gensec_security,
1733 call->in_auth_info.credentials);
1734 if (subreq == NULL) {
1735 return NT_STATUS_NO_MEMORY;
1737 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1739 return dcesrv_conn_auth_wait_setup(conn);
1742 static void dcesrv_alter_done(struct tevent_req *subreq)
1744 struct dcesrv_call_state *call =
1745 tevent_req_callback_data(subreq,
1746 struct dcesrv_call_state);
1747 struct dcesrv_connection *conn = call->conn;
1750 status = gensec_update_recv(subreq, call,
1751 &call->out_auth_info->credentials);
1752 TALLOC_FREE(subreq);
1754 status = dcesrv_auth_complete(call, status);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1757 dcesrv_conn_auth_wait_finished(conn, status);
1761 status = dcesrv_auth_reply(call);
1762 dcesrv_conn_auth_wait_finished(conn, status);
1767 possibly save the call for inspection with ndrdump
1769 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1773 const char *dump_dir;
1774 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1778 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1780 call->context->iface->name,
1781 call->pkt.u.request.opnum,
1783 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1784 DEBUG(0,("RPC SAVED %s\n", fname));
1790 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1792 TALLOC_CTX *frame = talloc_stackframe();
1793 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1794 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1795 const struct dcerpc_sec_vt_pcontext pcontext = {
1796 .abstract_syntax = call->context->iface->syntax_id,
1797 .transfer_syntax = call->context->transfer_syntax,
1799 const struct dcerpc_sec_vt_header2 header2 =
1800 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1801 enum ndr_err_code ndr_err;
1802 struct dcerpc_sec_verification_trailer *vt = NULL;
1803 NTSTATUS status = NT_STATUS_OK;
1806 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1808 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1810 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1811 status = ndr_map_error2ntstatus(ndr_err);
1815 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1816 &pcontext, &header2);
1818 status = NT_STATUS_ACCESS_DENIED;
1827 handle a dcerpc request packet
1829 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1831 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1832 enum dcerpc_transport_t transport =
1833 dcerpc_binding_get_transport(endpoint->ep_description);
1834 struct ndr_pull *pull;
1837 if (!call->conn->allow_request) {
1838 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1841 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1842 if (call->conn->auth_state.gensec_security &&
1843 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1844 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1847 if (call->context == NULL) {
1848 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1849 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1852 switch (call->conn->auth_state.auth_level) {
1853 case DCERPC_AUTH_LEVEL_NONE:
1854 case DCERPC_AUTH_LEVEL_PACKET:
1855 case DCERPC_AUTH_LEVEL_INTEGRITY:
1856 case DCERPC_AUTH_LEVEL_PRIVACY:
1859 if (!call->context->allow_connect) {
1862 addr = tsocket_address_string(call->conn->remote_address,
1865 DEBUG(2, ("%s: restrict auth_level_connect access "
1866 "to [%s] with auth[type=0x%x,level=0x%x] "
1867 "on [%s] from [%s]\n",
1868 __func__, call->context->iface->name,
1869 call->conn->auth_state.auth_type,
1870 call->conn->auth_state.auth_level,
1871 derpc_transport_string_by_transport(transport),
1873 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1878 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1881 addr = tsocket_address_string(call->conn->remote_address, call);
1883 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1884 "to [%s] with auth[type=0x%x,level=0x%x] "
1885 "on [%s] from [%s]\n",
1887 call->context->min_auth_level,
1888 call->context->iface->name,
1889 call->conn->auth_state.auth_type,
1890 call->conn->auth_state.auth_level,
1891 derpc_transport_string_by_transport(transport),
1893 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1896 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1897 NT_STATUS_HAVE_NO_MEMORY(pull);
1899 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1901 call->ndr_pull = pull;
1903 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1904 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1907 status = dcesrv_check_verification_trailer(call);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 uint32_t faultcode = DCERPC_FAULT_OTHER;
1910 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1911 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1913 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1914 nt_errstr(status)));
1915 return dcesrv_fault(call, faultcode);
1918 /* unravel the NDR for the packet */
1919 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1920 if (!NT_STATUS_IS_OK(status)) {
1921 uint8_t extra_flags = 0;
1922 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1923 /* we got an unknown call */
1924 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1925 call->pkt.u.request.opnum,
1926 call->context->iface->name));
1927 dcesrv_save_call(call, "unknown");
1928 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1930 dcesrv_save_call(call, "pullfail");
1932 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1935 if (pull->offset != pull->data_size) {
1936 dcesrv_save_call(call, "extrabytes");
1937 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1938 pull->data_size - pull->offset));
1941 /* call the dispatch function */
1942 status = call->context->iface->dispatch(call, call, call->r);
1943 if (!NT_STATUS_IS_OK(status)) {
1944 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1945 call->context->iface->name,
1946 call->pkt.u.request.opnum,
1947 dcerpc_errstr(pull, call->fault_code)));
1948 return dcesrv_fault(call, call->fault_code);
1951 /* add the call to the pending list */
1952 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1954 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1955 return NT_STATUS_OK;
1958 return dcesrv_reply(call);
1963 remove the call from the right list when freed
1965 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1967 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1971 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1973 return conn->local_address;
1976 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1978 return conn->remote_address;
1982 process some input to a dcerpc endpoint server.
1984 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1985 struct ncacn_packet *pkt,
1989 struct dcesrv_call_state *call;
1990 struct dcesrv_call_state *existing = NULL;
1992 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1994 data_blob_free(&blob);
1996 return NT_STATUS_NO_MEMORY;
1998 call->conn = dce_conn;
1999 call->event_ctx = dce_conn->event_ctx;
2000 call->msg_ctx = dce_conn->msg_ctx;
2001 call->state_flags = call->conn->state_flags;
2002 call->time = timeval_current();
2003 call->list = DCESRV_LIST_NONE;
2005 talloc_steal(call, pkt);
2006 talloc_steal(call, blob.data);
2009 talloc_set_destructor(call, dcesrv_call_dequeue);
2011 if (call->conn->allow_bind) {
2013 * Only one bind is possible per connection
2015 call->conn->allow_bind = false;
2016 return dcesrv_bind(call);
2019 /* we have to check the signing here, before combining the
2021 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2022 if (!call->conn->allow_request) {
2023 return dcesrv_fault_disconnect(call,
2024 DCERPC_NCA_S_PROTO_ERROR);
2027 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2029 call->pkt.u.request.stub_and_verifier.length,
2030 0, /* required_flags */
2031 DCERPC_PFC_FLAG_FIRST |
2032 DCERPC_PFC_FLAG_LAST |
2033 DCERPC_PFC_FLAG_PENDING_CANCEL |
2034 0x08 | /* this is not defined, but should be ignored */
2035 DCERPC_PFC_FLAG_CONC_MPX |
2036 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2037 DCERPC_PFC_FLAG_MAYBE |
2038 DCERPC_PFC_FLAG_OBJECT_UUID);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 return dcesrv_fault_disconnect(call,
2041 DCERPC_NCA_S_PROTO_ERROR);
2044 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2046 * We don't use dcesrv_fault_disconnect()
2047 * here, because we don't want to set
2048 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2050 * Note that we don't check against the negotiated
2051 * max_recv_frag, but a hard coded value.
2053 dcesrv_call_disconnect_after(call,
2054 "dcesrv_auth_request - frag_length too large");
2055 return dcesrv_fault(call,
2056 DCERPC_NCA_S_PROTO_ERROR);
2059 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2060 if (dce_conn->pending_call_list != NULL) {
2062 * concurrent requests are only allowed
2063 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2065 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2066 dcesrv_call_disconnect_after(call,
2067 "dcesrv_auth_request - "
2068 "existing pending call without CONN_MPX");
2069 return dcesrv_fault(call,
2070 DCERPC_NCA_S_PROTO_ERROR);
2073 /* only one request is possible in the fragmented list */
2074 if (dce_conn->incoming_fragmented_call_list != NULL) {
2075 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2077 * Without DCERPC_PFC_FLAG_CONC_MPX
2078 * we need to return the FAULT on the
2079 * already existing call.
2081 * This is important to get the
2082 * call_id and context_id right.
2085 call = dce_conn->incoming_fragmented_call_list;
2087 dcesrv_call_disconnect_after(call,
2088 "dcesrv_auth_request - "
2089 "existing fragmented call");
2090 return dcesrv_fault(call,
2091 DCERPC_NCA_S_PROTO_ERROR);
2093 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2094 return dcesrv_fault_disconnect(call,
2095 DCERPC_FAULT_NO_CALL_ACTIVE);
2097 call->context = dcesrv_find_context(call->conn,
2098 call->pkt.u.request.context_id);
2099 if (call->context == NULL) {
2100 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2101 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2104 const struct dcerpc_request *nr = &call->pkt.u.request;
2105 const struct dcerpc_request *er = NULL;
2108 existing = dcesrv_find_fragmented_call(dce_conn,
2110 if (existing == NULL) {
2111 dcesrv_call_disconnect_after(call,
2112 "dcesrv_auth_request - "
2113 "no existing fragmented call");
2114 return dcesrv_fault(call,
2115 DCERPC_NCA_S_PROTO_ERROR);
2117 er = &existing->pkt.u.request;
2119 if (call->pkt.ptype != existing->pkt.ptype) {
2120 /* trying to play silly buggers are we? */
2121 return dcesrv_fault_disconnect(existing,
2122 DCERPC_NCA_S_PROTO_ERROR);
2124 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2127 return dcesrv_fault_disconnect(existing,
2128 DCERPC_NCA_S_PROTO_ERROR);
2130 if (nr->context_id != er->context_id) {
2131 return dcesrv_fault_disconnect(existing,
2132 DCERPC_NCA_S_PROTO_ERROR);
2134 if (nr->opnum != er->opnum) {
2135 return dcesrv_fault_disconnect(existing,
2136 DCERPC_NCA_S_PROTO_ERROR);
2141 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2143 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2145 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2146 payload_offset += 16;
2149 ok = dcesrv_auth_pkt_pull(call, &blob,
2150 0, /* required_flags */
2151 DCERPC_PFC_FLAG_FIRST |
2152 DCERPC_PFC_FLAG_LAST |
2153 DCERPC_PFC_FLAG_PENDING_CANCEL |
2154 0x08 | /* this is not defined, but should be ignored */
2155 DCERPC_PFC_FLAG_CONC_MPX |
2156 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2157 DCERPC_PFC_FLAG_MAYBE |
2158 DCERPC_PFC_FLAG_OBJECT_UUID,
2160 &call->pkt.u.request.stub_and_verifier);
2163 * We don't use dcesrv_fault_disconnect()
2164 * here, because we don't want to set
2165 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2167 dcesrv_call_disconnect_after(call,
2168 "dcesrv_auth_request - failed");
2169 if (call->fault_code == 0) {
2170 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2172 return dcesrv_fault(call, call->fault_code);
2176 /* see if this is a continued packet */
2177 if (existing != NULL) {
2178 struct dcerpc_request *er = &existing->pkt.u.request;
2179 const struct dcerpc_request *nr = &call->pkt.u.request;
2185 * Up to 4 MByte are allowed by all fragments
2187 available = dce_conn->max_total_request_size;
2188 if (er->stub_and_verifier.length > available) {
2189 dcesrv_call_disconnect_after(existing,
2190 "dcesrv_auth_request - existing payload too large");
2191 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2193 available -= er->stub_and_verifier.length;
2194 if (nr->alloc_hint > available) {
2195 dcesrv_call_disconnect_after(existing,
2196 "dcesrv_auth_request - alloc hint too large");
2197 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2199 if (nr->stub_and_verifier.length > available) {
2200 dcesrv_call_disconnect_after(existing,
2201 "dcesrv_auth_request - new payload too large");
2202 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2204 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2205 /* allocate at least 1 byte */
2206 alloc_hint = MAX(alloc_hint, 1);
2207 alloc_size = er->stub_and_verifier.length +
2208 nr->stub_and_verifier.length;
2209 alloc_size = MAX(alloc_size, alloc_hint);
2211 er->stub_and_verifier.data =
2212 talloc_realloc(existing,
2213 er->stub_and_verifier.data,
2214 uint8_t, alloc_size);
2215 if (er->stub_and_verifier.data == NULL) {
2217 return dcesrv_fault_with_flags(existing,
2218 DCERPC_FAULT_OUT_OF_RESOURCES,
2219 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2221 memcpy(er->stub_and_verifier.data +
2222 er->stub_and_verifier.length,
2223 nr->stub_and_verifier.data,
2224 nr->stub_and_verifier.length);
2225 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2227 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2233 /* this may not be the last pdu in the chain - if its isn't then
2234 just put it on the incoming_fragmented_call_list and wait for the rest */
2235 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2236 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2238 * Up to 4 MByte are allowed by all fragments
2240 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2241 dcesrv_call_disconnect_after(call,
2242 "dcesrv_auth_request - initial alloc hint too large");
2243 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2245 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2246 return NT_STATUS_OK;
2249 /* This removes any fragments we may have had stashed away */
2250 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2252 switch (call->pkt.ptype) {
2253 case DCERPC_PKT_BIND:
2254 status = dcesrv_bind_nak(call,
2255 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2257 case DCERPC_PKT_AUTH3:
2258 status = dcesrv_auth3(call);
2260 case DCERPC_PKT_ALTER:
2261 status = dcesrv_alter(call);
2263 case DCERPC_PKT_REQUEST:
2264 status = dcesrv_request(call);
2266 case DCERPC_PKT_CO_CANCEL:
2267 case DCERPC_PKT_ORPHANED:
2269 * Window just ignores CO_CANCEL and ORPHANED,
2272 status = NT_STATUS_OK;
2275 case DCERPC_PKT_BIND_ACK:
2276 case DCERPC_PKT_BIND_NAK:
2277 case DCERPC_PKT_ALTER_RESP:
2278 case DCERPC_PKT_RESPONSE:
2279 case DCERPC_PKT_FAULT:
2280 case DCERPC_PKT_SHUTDOWN:
2282 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2286 /* if we are going to be sending a reply then add
2287 it to the list of pending calls. We add it to the end to keep the call
2288 list in the order we will answer */
2289 if (!NT_STATUS_IS_OK(status)) {
2296 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2297 struct loadparm_context *lp_ctx,
2298 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2301 struct dcesrv_context *dce_ctx;
2304 if (!endpoint_servers) {
2305 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2306 return NT_STATUS_INTERNAL_ERROR;
2309 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2310 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2312 if (uid_wrapper_enabled()) {
2313 setenv("UID_WRAPPER_MYUID", "1", 1);
2315 dce_ctx->initial_euid = geteuid();
2316 if (uid_wrapper_enabled()) {
2317 unsetenv("UID_WRAPPER_MYUID");
2320 dce_ctx->endpoint_list = NULL;
2321 dce_ctx->lp_ctx = lp_ctx;
2322 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2323 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2324 dce_ctx->broken_connections = NULL;
2326 for (i=0;endpoint_servers[i];i++) {
2327 const struct dcesrv_endpoint_server *ep_server;
2329 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2331 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2332 return NT_STATUS_INTERNAL_ERROR;
2335 status = ep_server->init_server(dce_ctx, ep_server);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2338 nt_errstr(status)));
2343 *_dce_ctx = dce_ctx;
2344 return NT_STATUS_OK;
2347 /* the list of currently registered DCERPC endpoint servers.
2349 static struct ep_server {
2350 struct dcesrv_endpoint_server *ep_server;
2351 } *ep_servers = NULL;
2352 static int num_ep_servers;
2355 register a DCERPC endpoint server.
2357 The 'name' can be later used by other backends to find the operations
2358 structure for this backend.
2361 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2364 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2365 /* its already registered! */
2366 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2368 return NT_STATUS_OBJECT_NAME_COLLISION;
2371 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2373 smb_panic("out of memory in dcerpc_register");
2376 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2377 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2381 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2384 return NT_STATUS_OK;
2388 return the operations structure for a named backend of the specified type
2390 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2394 for (i=0;i<num_ep_servers;i++) {
2395 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2396 return ep_servers[i].ep_server;
2403 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2405 static bool initialized;
2406 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2407 STATIC_dcerpc_server_MODULES_PROTO;
2408 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2409 init_module_fn *shared_init;
2416 shared_init = load_samba_modules(NULL, "dcerpc_server");
2418 run_init_functions(NULL, static_init);
2419 run_init_functions(NULL, shared_init);
2421 talloc_free(shared_init);
2425 return the DCERPC module version, and the size of some critical types
2426 This can be used by endpoint server modules to either detect compilation errors, or provide
2427 multiple implementations for different smbd compilation options in one module
2429 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2431 static const struct dcesrv_critical_sizes critical_sizes = {
2432 DCERPC_MODULE_VERSION,
2433 sizeof(struct dcesrv_context),
2434 sizeof(struct dcesrv_endpoint),
2435 sizeof(struct dcesrv_endpoint_server),
2436 sizeof(struct dcesrv_interface),
2437 sizeof(struct dcesrv_if_list),
2438 sizeof(struct dcesrv_connection),
2439 sizeof(struct dcesrv_call_state),
2440 sizeof(struct dcesrv_auth),
2441 sizeof(struct dcesrv_handle)
2444 return &critical_sizes;
2447 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2449 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2450 struct stream_connection *srv_conn;
2451 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2452 struct stream_connection);
2454 dce_conn->wait_send = NULL;
2455 dce_conn->wait_recv = NULL;
2456 dce_conn->wait_private = NULL;
2458 dce_conn->allow_bind = false;
2459 dce_conn->allow_auth3 = false;
2460 dce_conn->allow_alter = false;
2461 dce_conn->allow_request = false;
2463 if (dce_conn->pending_call_list == NULL) {
2464 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2466 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2467 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2471 if (dce_conn->terminate != NULL) {
2475 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2477 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2478 if (dce_conn->terminate == NULL) {
2479 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2481 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2484 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2486 struct dcesrv_connection *cur, *next;
2488 next = dce_ctx->broken_connections;
2489 while (next != NULL) {
2493 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2494 struct dcesrv_connection_context *context_cur, *context_next;
2496 context_next = cur->contexts;
2497 while (context_next != NULL) {
2498 context_cur = context_next;
2499 context_next = context_cur->next;
2501 dcesrv_connection_context_destructor(context_cur);
2505 dcesrv_terminate_connection(cur, cur->terminate);
2509 /* We need this include to be able to compile on some plateforms
2510 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2512 * It has to be that deep because otherwise we have a conflict on
2513 * const struct dcesrv_interface declaration.
2514 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2515 * which conflict with the bind used before.
2517 #include "system/network.h"
2519 struct dcesrv_sock_reply_state {
2520 struct dcesrv_connection *dce_conn;
2521 struct dcesrv_call_state *call;
2525 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2526 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2528 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2530 struct dcesrv_call_state *call;
2532 call = dce_conn->call_list;
2533 if (!call || !call->replies) {
2537 while (call->replies) {
2538 struct data_blob_list_item *rep = call->replies;
2539 struct dcesrv_sock_reply_state *substate;
2540 struct tevent_req *subreq;
2542 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2544 dcesrv_terminate_connection(dce_conn, "no memory");
2548 substate->dce_conn = dce_conn;
2549 substate->call = NULL;
2551 DLIST_REMOVE(call->replies, rep);
2553 if (call->replies == NULL && call->terminate_reason == NULL) {
2554 substate->call = call;
2557 substate->iov.iov_base = (void *) rep->blob.data;
2558 substate->iov.iov_len = rep->blob.length;
2560 subreq = tstream_writev_queue_send(substate,
2561 dce_conn->event_ctx,
2563 dce_conn->send_queue,
2566 dcesrv_terminate_connection(dce_conn, "no memory");
2569 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2573 if (call->terminate_reason != NULL) {
2574 struct tevent_req *subreq;
2576 subreq = tevent_queue_wait_send(call,
2577 dce_conn->event_ctx,
2578 dce_conn->send_queue);
2580 dcesrv_terminate_connection(dce_conn, __location__);
2583 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2587 DLIST_REMOVE(call->conn->call_list, call);
2588 call->list = DCESRV_LIST_NONE;
2591 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2593 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2594 struct dcesrv_sock_reply_state);
2598 struct dcesrv_call_state *call = substate->call;
2600 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2601 TALLOC_FREE(subreq);
2603 status = map_nt_error_from_unix_common(sys_errno);
2604 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2608 talloc_free(substate);
2614 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2616 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2618 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2619 struct dcesrv_call_state);
2623 /* make sure we stop send queue before removing subreq */
2624 tevent_queue_stop(call->conn->send_queue);
2626 ok = tevent_queue_wait_recv(subreq);
2627 TALLOC_FREE(subreq);
2629 dcesrv_terminate_connection(call->conn, __location__);
2633 /* disconnect after 200 usecs */
2634 tv = timeval_current_ofs_usec(200);
2635 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2636 if (subreq == NULL) {
2637 dcesrv_terminate_connection(call->conn, __location__);
2640 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2644 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2646 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2647 struct dcesrv_call_state);
2650 ok = tevent_wakeup_recv(subreq);
2651 TALLOC_FREE(subreq);
2653 dcesrv_terminate_connection(call->conn, __location__);
2657 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2660 struct dcesrv_socket_context {
2661 const struct dcesrv_endpoint *endpoint;
2662 struct dcesrv_context *dcesrv_ctx;
2666 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2668 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2671 struct dcesrv_socket_context *dcesrv_sock =
2672 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2673 enum dcerpc_transport_t transport =
2674 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2675 struct dcesrv_connection *dcesrv_conn = NULL;
2677 struct tevent_req *subreq;
2678 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2680 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2682 if (!srv_conn->session_info) {
2683 status = auth_anonymous_session_info(srv_conn,
2685 &srv_conn->session_info);
2686 if (!NT_STATUS_IS_OK(status)) {
2687 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2688 nt_errstr(status)));
2689 stream_terminate_connection(srv_conn, nt_errstr(status));
2695 * This fills in dcesrv_conn->endpoint with the endpoint
2696 * associated with the socket. From this point on we know
2697 * which (group of) services we are handling, but not the
2698 * specific interface.
2701 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2703 dcesrv_sock->endpoint,
2704 srv_conn->session_info,
2705 srv_conn->event.ctx,
2707 srv_conn->server_id,
2708 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2710 if (!NT_STATUS_IS_OK(status)) {
2711 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2712 nt_errstr(status)));
2713 stream_terminate_connection(srv_conn, nt_errstr(status));
2717 dcesrv_conn->transport.private_data = srv_conn;
2718 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2720 TALLOC_FREE(srv_conn->event.fde);
2722 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2723 if (!dcesrv_conn->send_queue) {
2724 status = NT_STATUS_NO_MEMORY;
2725 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2726 nt_errstr(status)));
2727 stream_terminate_connection(srv_conn, nt_errstr(status));
2731 if (transport == NCACN_NP) {
2732 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2733 &srv_conn->tstream);
2735 ret = tstream_bsd_existing_socket(dcesrv_conn,
2736 socket_get_fd(srv_conn->socket),
2737 &dcesrv_conn->stream);
2739 status = map_nt_error_from_unix_common(errno);
2740 DEBUG(0, ("dcesrv_sock_accept: "
2741 "failed to setup tstream: %s\n",
2742 nt_errstr(status)));
2743 stream_terminate_connection(srv_conn, nt_errstr(status));
2746 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2749 dcesrv_conn->local_address = srv_conn->local_address;
2750 dcesrv_conn->remote_address = srv_conn->remote_address;
2752 if (transport == NCALRPC) {
2757 sock_fd = socket_get_fd(srv_conn->socket);
2758 if (sock_fd == -1) {
2759 stream_terminate_connection(
2760 srv_conn, "socket_get_fd failed\n");
2764 ret = getpeereid(sock_fd, &uid, &gid);
2766 status = map_nt_error_from_unix_common(errno);
2767 DEBUG(0, ("dcesrv_sock_accept: "
2768 "getpeereid() failed for NCALRPC: %s\n",
2769 nt_errstr(status)));
2770 stream_terminate_connection(srv_conn, nt_errstr(status));
2773 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2774 struct tsocket_address *r = NULL;
2776 ret = tsocket_address_unix_from_path(dcesrv_conn,
2777 AS_SYSTEM_MAGIC_PATH_TOKEN,
2780 status = map_nt_error_from_unix_common(errno);
2781 DEBUG(0, ("dcesrv_sock_accept: "
2782 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2783 nt_errstr(status)));
2784 stream_terminate_connection(srv_conn, nt_errstr(status));
2787 dcesrv_conn->remote_address = r;
2791 srv_conn->private_data = dcesrv_conn;
2793 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2794 dcesrv_conn->event_ctx,
2795 dcesrv_conn->stream);
2797 status = NT_STATUS_NO_MEMORY;
2798 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2799 nt_errstr(status)));
2800 stream_terminate_connection(srv_conn, nt_errstr(status));
2803 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2808 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2810 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2812 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2813 struct dcesrv_connection);
2814 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2815 struct ncacn_packet *pkt;
2819 if (dce_conn->terminate) {
2821 * if the current connection is broken
2822 * we need to clean it up before any other connection
2824 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2825 dcesrv_cleanup_broken_connections(dce_ctx);
2829 dcesrv_cleanup_broken_connections(dce_ctx);
2831 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2833 TALLOC_FREE(subreq);
2834 if (!NT_STATUS_IS_OK(status)) {
2835 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2839 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2846 * This is used to block the connection during
2847 * pending authentication.
2849 if (dce_conn->wait_send != NULL) {
2850 subreq = dce_conn->wait_send(dce_conn,
2851 dce_conn->event_ctx,
2852 dce_conn->wait_private);
2854 status = NT_STATUS_NO_MEMORY;
2855 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2858 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2862 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2863 dce_conn->event_ctx,
2866 status = NT_STATUS_NO_MEMORY;
2867 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2870 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2873 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2875 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2876 struct dcesrv_connection);
2877 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2880 if (dce_conn->terminate) {
2882 * if the current connection is broken
2883 * we need to clean it up before any other connection
2885 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2886 dcesrv_cleanup_broken_connections(dce_ctx);
2890 dcesrv_cleanup_broken_connections(dce_ctx);
2892 status = dce_conn->wait_recv(subreq);
2893 dce_conn->wait_send = NULL;
2894 dce_conn->wait_recv = NULL;
2895 dce_conn->wait_private = NULL;
2896 TALLOC_FREE(subreq);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2902 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2903 dce_conn->event_ctx,
2906 status = NT_STATUS_NO_MEMORY;
2907 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2910 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2913 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2915 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2916 struct dcesrv_connection);
2917 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2920 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2922 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2923 struct dcesrv_connection);
2924 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2928 static const struct stream_server_ops dcesrv_stream_ops = {
2930 .accept_connection = dcesrv_sock_accept,
2931 .recv_handler = dcesrv_sock_recv,
2932 .send_handler = dcesrv_sock_send,
2935 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2936 struct loadparm_context *lp_ctx,
2937 struct dcesrv_endpoint *e,
2938 struct tevent_context *event_ctx,
2939 const struct model_ops *model_ops,
2940 void *process_context)
2942 struct dcesrv_socket_context *dcesrv_sock;
2945 const char *endpoint;
2947 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2948 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2950 /* remember the endpoint of this socket */
2951 dcesrv_sock->endpoint = e;
2952 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2954 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2956 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2957 model_ops, &dcesrv_stream_ops,
2958 "unix", endpoint, &port,
2959 lpcfg_socket_options(lp_ctx),
2960 dcesrv_sock, process_context);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2963 endpoint, nt_errstr(status)));
2969 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2970 struct loadparm_context *lp_ctx,
2971 struct dcesrv_endpoint *e,
2972 struct tevent_context *event_ctx,
2973 const struct model_ops *model_ops,
2974 void *process_context)
2976 struct dcesrv_socket_context *dcesrv_sock;
2980 const char *endpoint;
2982 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2984 if (endpoint == NULL) {
2986 * No identifier specified: use DEFAULT.
2988 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2989 * no endpoint and let the epmapper worry about it.
2991 endpoint = "DEFAULT";
2992 status = dcerpc_binding_set_string_option(e->ep_description,
2995 if (!NT_STATUS_IS_OK(status)) {
2996 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2997 nt_errstr(status)));
3002 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
3005 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3006 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3008 /* remember the endpoint of this socket */
3009 dcesrv_sock->endpoint = e;
3010 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3012 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3013 model_ops, &dcesrv_stream_ops,
3014 "unix", full_path, &port,
3015 lpcfg_socket_options(lp_ctx),
3016 dcesrv_sock, process_context);
3017 if (!NT_STATUS_IS_OK(status)) {
3018 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3019 endpoint, full_path, nt_errstr(status)));
3024 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3025 struct loadparm_context *lp_ctx,
3026 struct dcesrv_endpoint *e,
3027 struct tevent_context *event_ctx,
3028 const struct model_ops *model_ops,
3029 void *process_context)
3031 struct dcesrv_socket_context *dcesrv_sock;
3033 const char *endpoint;
3035 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3036 if (endpoint == NULL) {
3037 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3038 return NT_STATUS_INVALID_PARAMETER;
3041 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3042 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3044 /* remember the endpoint of this socket */
3045 dcesrv_sock->endpoint = e;
3046 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3048 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3049 model_ops, &dcesrv_stream_ops,
3051 dcesrv_sock, process_context);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3054 endpoint, nt_errstr(status)));
3058 return NT_STATUS_OK;
3062 add a socket address to the list of events, one event per dcerpc endpoint
3064 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3065 struct dcesrv_endpoint *e,
3066 struct tevent_context *event_ctx,
3067 const struct model_ops *model_ops,
3068 const char *address,
3069 void *process_context)
3071 struct dcesrv_socket_context *dcesrv_sock;
3074 const char *endpoint;
3077 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3078 if (endpoint != NULL) {
3079 port = atoi(endpoint);
3082 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3083 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3085 /* remember the endpoint of this socket */
3086 dcesrv_sock->endpoint = e;
3087 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3089 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3090 model_ops, &dcesrv_stream_ops,
3091 "ip", address, &port,
3092 lpcfg_socket_options(dce_ctx->lp_ctx),
3093 dcesrv_sock, process_context);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 struct dcesrv_if_list *iface;
3096 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3098 for (iface = e->interface_list; iface; iface = iface->next) {
3099 DEBUGADD(0, ("%s ", iface->iface.name));
3101 DEBUGADD(0, ("failed - %s",
3102 nt_errstr(status)));
3106 snprintf(port_str, sizeof(port_str), "%u", port);
3108 status = dcerpc_binding_set_string_option(e->ep_description,
3109 "endpoint", port_str);
3110 if (!NT_STATUS_IS_OK(status)) {
3111 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3112 port_str, nt_errstr(status)));
3115 struct dcesrv_if_list *iface;
3116 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3117 address, port_str));
3118 for (iface = e->interface_list; iface; iface = iface->next) {
3119 DEBUGADD(4, ("%s ", iface->iface.name));
3121 DEBUGADD(4, ("\n"));
3124 return NT_STATUS_OK;
3127 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3129 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3130 struct loadparm_context *lp_ctx,
3131 struct dcesrv_endpoint *e,
3132 struct tevent_context *event_ctx,
3133 const struct model_ops *model_ops,
3134 void *process_context)
3138 /* Add TCP/IP sockets */
3139 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3142 struct interface *ifaces;
3144 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3146 num_interfaces = iface_list_count(ifaces);
3147 for(i = 0; i < num_interfaces; i++) {
3148 const char *address = iface_list_n_ip(ifaces, i);
3149 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3152 NT_STATUS_NOT_OK_RETURN(status);
3157 size_t num_binds = 0;
3158 wcard = iface_list_wildcard(dce_ctx);
3159 NT_STATUS_HAVE_NO_MEMORY(wcard);
3160 for (i=0; wcard[i]; i++) {
3161 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3162 model_ops, wcard[i],
3164 if (NT_STATUS_IS_OK(status)) {
3169 if (num_binds == 0) {
3170 return NT_STATUS_INVALID_PARAMETER_MIX;
3174 return NT_STATUS_OK;
3177 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3178 struct loadparm_context *lp_ctx,
3179 struct dcesrv_endpoint *e,
3180 struct tevent_context *event_ctx,
3181 const struct model_ops *model_ops,
3182 void *process_context)
3184 enum dcerpc_transport_t transport =
3185 dcerpc_binding_get_transport(e->ep_description);
3187 switch (transport) {
3188 case NCACN_UNIX_STREAM:
3189 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3190 model_ops, process_context);
3193 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3194 model_ops, process_context);
3197 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3198 model_ops, process_context);
3201 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3202 model_ops, process_context);
3205 return NT_STATUS_NOT_SUPPORTED;
3211 * retrieve credentials from a dce_call
3213 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3215 return dce_call->conn->auth_state.session_info->credentials;
3219 * returns true if this is an authenticated call
3221 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3223 enum security_user_level level;
3224 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3225 return level >= SECURITY_USER;
3229 * retrieve account_name for a dce_call
3231 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3233 return dce_call->context->conn->auth_state.session_info->info->account_name;
3237 * retrieve session_info from a dce_call
3239 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3241 return dce_call->context->conn->auth_state.session_info;