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 _PUBLIC_ 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 struct dcesrv_connection *p;
557 return NT_STATUS_ACCESS_DENIED;
560 p = talloc_zero(mem_ctx, struct dcesrv_connection);
561 NT_STATUS_HAVE_NO_MEMORY(p);
563 if (!talloc_reference(p, session_info)) {
565 return NT_STATUS_NO_MEMORY;
568 p->dce_ctx = dce_ctx;
570 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
571 p->auth_state.session_info = session_info;
572 p->auth_state.session_key = dcesrv_generic_session_key;
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;
583 * For now we only support NDR32.
585 p->preferred_transfer = &ndr_transfer_syntax_ndr;
592 move a call from an existing linked list to the specified list. This
593 prevents bugs where we forget to remove the call from a previous
596 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
597 enum dcesrv_call_list list)
599 switch (call->list) {
600 case DCESRV_LIST_NONE:
602 case DCESRV_LIST_CALL_LIST:
603 DLIST_REMOVE(call->conn->call_list, call);
605 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
606 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
608 case DCESRV_LIST_PENDING_CALL_LIST:
609 DLIST_REMOVE(call->conn->pending_call_list, call);
614 case DCESRV_LIST_NONE:
616 case DCESRV_LIST_CALL_LIST:
617 DLIST_ADD_END(call->conn->call_list, call);
619 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
620 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
622 case DCESRV_LIST_PENDING_CALL_LIST:
623 DLIST_ADD_END(call->conn->pending_call_list, call);
628 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
631 if (call->conn->terminate != NULL) {
635 call->conn->allow_bind = false;
636 call->conn->allow_alter = false;
637 call->conn->allow_auth3 = false;
638 call->conn->allow_request = false;
640 call->terminate_reason = talloc_strdup(call, reason);
641 if (call->terminate_reason == NULL) {
642 call->terminate_reason = __location__;
647 return a dcerpc bind_nak
649 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
651 struct ncacn_packet pkt;
652 struct dcerpc_bind_nak_version version;
653 struct data_blob_list_item *rep;
655 static const uint8_t _pad[3] = { 0, };
658 * We add the call to the pending_call_list
659 * in order to defer the termination.
661 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
663 /* setup a bind_nak */
664 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
666 pkt.call_id = call->pkt.call_id;
667 pkt.ptype = DCERPC_PKT_BIND_NAK;
668 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
669 pkt.u.bind_nak.reject_reason = reason;
670 version.rpc_vers = 5;
671 version.rpc_vers_minor = 0;
672 pkt.u.bind_nak.num_versions = 1;
673 pkt.u.bind_nak.versions = &version;
674 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
676 rep = talloc_zero(call, struct data_blob_list_item);
678 return NT_STATUS_NO_MEMORY;
681 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
682 if (!NT_STATUS_IS_OK(status)) {
686 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
688 DLIST_ADD_END(call->replies, rep);
689 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
691 if (call->conn->call_list && call->conn->call_list->replies) {
692 if (call->conn->transport.report_output_data) {
693 call->conn->transport.report_output_data(call->conn);
700 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
704 * We add the call to the pending_call_list
705 * in order to defer the termination.
707 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
709 return dcesrv_fault_with_flags(call, fault_code,
710 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
713 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
715 DLIST_REMOVE(c->conn->contexts, c);
717 if (c->iface && c->iface->unbind) {
718 c->iface->unbind(c, c->iface);
725 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
727 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
728 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
729 enum dcerpc_transport_t transport =
730 dcerpc_binding_get_transport(endpoint->ep_description);
731 struct dcesrv_connection_context *context = dce_call->context;
732 const struct dcesrv_interface *iface = context->iface;
734 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
736 if (transport == NCALRPC) {
737 context->allow_connect = true;
742 * allow overwrite per interface
743 * allow dcerpc auth level connect:<interface>
745 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
746 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
747 "allow dcerpc auth level connect",
749 context->allow_connect);
752 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
753 const struct dcesrv_interface *iface)
755 if (dce_call->context == NULL) {
756 return NT_STATUS_INTERNAL_ERROR;
760 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
761 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
763 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
767 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
768 const struct dcesrv_interface *iface)
770 if (dce_call->context == NULL) {
771 return NT_STATUS_INTERNAL_ERROR;
774 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
778 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
779 const struct dcesrv_interface *iface)
781 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
782 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
783 enum dcerpc_transport_t transport =
784 dcerpc_binding_get_transport(endpoint->ep_description);
785 struct dcesrv_connection_context *context = dce_call->context;
787 if (context == NULL) {
788 return NT_STATUS_INTERNAL_ERROR;
791 if (transport == NCALRPC) {
792 context->allow_connect = true;
797 * allow overwrite per interface
798 * allow dcerpc auth level connect:<interface>
800 context->allow_connect = false;
801 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
802 "allow dcerpc auth level connect",
804 context->allow_connect);
808 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
809 const struct dcesrv_interface *iface)
811 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
812 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
813 enum dcerpc_transport_t transport =
814 dcerpc_binding_get_transport(endpoint->ep_description);
815 struct dcesrv_connection_context *context = dce_call->context;
817 if (context == NULL) {
818 return NT_STATUS_INTERNAL_ERROR;
821 if (transport == NCALRPC) {
822 context->allow_connect = true;
827 * allow overwrite per interface
828 * allow dcerpc auth level connect:<interface>
830 context->allow_connect = true;
831 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
832 "allow dcerpc auth level connect",
834 context->allow_connect);
838 struct dcesrv_conn_auth_wait_context {
839 struct tevent_req *req;
844 struct dcesrv_conn_auth_wait_state {
848 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
849 struct tevent_context *ev,
852 struct dcesrv_conn_auth_wait_context *auth_wait =
853 talloc_get_type_abort(private_data,
854 struct dcesrv_conn_auth_wait_context);
855 struct tevent_req *req = NULL;
856 struct dcesrv_conn_auth_wait_state *state = NULL;
858 req = tevent_req_create(mem_ctx, &state,
859 struct dcesrv_conn_auth_wait_state);
863 auth_wait->req = req;
865 tevent_req_defer_callback(req, ev);
867 if (!auth_wait->done) {
871 if (tevent_req_nterror(req, auth_wait->status)) {
872 return tevent_req_post(req, ev);
875 tevent_req_done(req);
876 return tevent_req_post(req, ev);
879 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
881 return tevent_req_simple_recv_ntstatus(req);
884 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
886 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
888 if (conn->wait_send != NULL) {
889 return NT_STATUS_INTERNAL_ERROR;
892 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
893 if (auth_wait == NULL) {
894 return NT_STATUS_NO_MEMORY;
897 conn->wait_private = auth_wait;
898 conn->wait_send = dcesrv_conn_auth_wait_send;
899 conn->wait_recv = dcesrv_conn_auth_wait_recv;
903 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
906 struct dcesrv_conn_auth_wait_context *auth_wait =
907 talloc_get_type_abort(conn->wait_private,
908 struct dcesrv_conn_auth_wait_context);
910 auth_wait->done = true;
911 auth_wait->status = status;
913 if (auth_wait->req == NULL) {
917 if (tevent_req_nterror(auth_wait->req, status)) {
921 tevent_req_done(auth_wait->req);
924 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
926 static void dcesrv_bind_done(struct tevent_req *subreq);
929 handle a bind request
931 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
933 struct dcesrv_connection *conn = call->conn;
934 struct ncacn_packet *pkt = &call->ack_pkt;
936 uint32_t extra_flags = 0;
937 uint16_t max_req = 0;
938 uint16_t max_rep = 0;
939 const char *ep_prefix = "";
940 const char *endpoint = NULL;
941 struct dcesrv_auth *auth = &call->conn->auth_state;
942 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
943 struct dcerpc_ack_ctx *ack_features = NULL;
944 struct tevent_req *subreq = NULL;
947 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
949 call->pkt.u.bind.auth_info.length,
950 0, /* required flags */
951 DCERPC_PFC_FLAG_FIRST |
952 DCERPC_PFC_FLAG_LAST |
953 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
954 0x08 | /* this is not defined, but should be ignored */
955 DCERPC_PFC_FLAG_CONC_MPX |
956 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
957 DCERPC_PFC_FLAG_MAYBE |
958 DCERPC_PFC_FLAG_OBJECT_UUID);
959 if (!NT_STATUS_IS_OK(status)) {
960 return dcesrv_bind_nak(call,
961 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
964 /* max_recv_frag and max_xmit_frag result always in the same value! */
965 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
966 call->pkt.u.bind.max_recv_frag);
968 * The values are between 2048 and 5840 tested against Windows 2012R2
969 * via ncacn_ip_tcp on port 135.
971 max_req = MAX(2048, max_req);
972 max_rep = MIN(max_req, call->conn->max_recv_frag);
973 /* They are truncated to an 8 byte boundary. */
976 /* max_recv_frag and max_xmit_frag result always in the same value! */
977 call->conn->max_recv_frag = max_rep;
978 call->conn->max_xmit_frag = max_rep;
981 if provided, check the assoc_group is valid
983 if (call->pkt.u.bind.assoc_group_id != 0) {
984 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
986 call->pkt.u.bind.assoc_group_id);
988 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
989 call->conn->dce_ctx);
993 * The NETLOGON server does not use handles and so
994 * there is no need to support association groups, but
995 * we need to give back a number regardless.
997 * We have to do this when it is not run as a single process,
998 * because then it can't see the other valid association
999 * groups. We handle this genericly for all endpoints not
1000 * running in single process mode.
1002 * We know which endpoint we are on even before checking the
1003 * iface UUID, so for simplicity we enforce the same policy
1004 * for all interfaces on the endpoint.
1006 * This means that where NETLOGON
1007 * shares an endpoint (such as ncalrpc or of 'lsa over
1008 * netlogon' is set) we will still check association groups.
1012 if (call->conn->assoc_group == NULL &&
1013 !call->conn->endpoint->use_single_process) {
1014 call->conn->assoc_group
1015 = dcesrv_assoc_group_new(call->conn,
1016 call->conn->dce_ctx);
1018 if (call->conn->assoc_group == NULL) {
1019 return dcesrv_bind_nak(call, 0);
1022 if (call->pkt.u.bind.num_contexts < 1) {
1023 return dcesrv_bind_nak(call, 0);
1026 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1027 call->pkt.u.bind.num_contexts);
1028 if (ack_ctx_list == NULL) {
1029 return dcesrv_bind_nak(call, 0);
1033 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1034 * dcesrv_check_or_create_context()) and do some protocol validation
1035 * and set sane defaults.
1037 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1038 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1039 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1040 bool is_feature = false;
1041 uint64_t features = 0;
1043 if (c->num_transfer_syntaxes == 0) {
1044 return dcesrv_bind_nak(call, 0);
1047 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1048 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1051 * It's only treated as bind time feature request, if the first
1052 * transfer_syntax matches, all others are ignored.
1054 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1060 if (ack_features != NULL) {
1062 * Only one bind time feature context is allowed.
1064 return dcesrv_bind_nak(call, 0);
1068 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1069 a->reason.negotiate = 0;
1070 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1071 /* not supported yet */
1073 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1074 a->reason.negotiate |=
1075 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1078 call->conn->bind_time_features = a->reason.negotiate;
1082 * Try to negotiate one new presentation context.
1084 * Deep in here we locate the iface (by uuid) that the client
1085 * requested, from the list of interfaces on the
1086 * call->conn->endpoint, and call iface->bind() on that iface.
1088 * call->conn was set up at the accept() of the socket, and
1089 * call->conn->endpoint has a list of interfaces restricted to
1090 * this port or pipe.
1092 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1093 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1094 return dcesrv_bind_nak(call, 0);
1096 if (!NT_STATUS_IS_OK(status)) {
1101 * At this point we still don't know which interface (eg
1102 * netlogon, lsa, drsuapi) the caller requested in this bind!
1103 * The most recently added context is available as the first
1104 * element in the linked list at call->conn->contexts, that is
1105 * call->conn->contexts->iface, but they may not have
1106 * requested one at all!
1109 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1110 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1111 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1112 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1115 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1116 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1120 * After finding the interface and setting up the NDR
1121 * transport negotiation etc, handle any authentication that
1122 * is being requested.
1124 if (!dcesrv_auth_bind(call)) {
1126 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1128 * With DCERPC_AUTH_LEVEL_NONE, we get the
1129 * reject_reason in auth->auth_context_id.
1131 return dcesrv_bind_nak(call, auth->auth_context_id);
1135 * This must a be a temporary failure e.g. talloc or invalid
1136 * configuration, e.g. no machine account.
1138 return dcesrv_bind_nak(call,
1139 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1142 /* setup a bind_ack */
1143 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1144 pkt->auth_length = 0;
1145 pkt->call_id = call->pkt.call_id;
1146 pkt->ptype = DCERPC_PKT_BIND_ACK;
1147 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1148 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1149 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1150 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1152 endpoint = dcerpc_binding_get_string_option(
1153 call->conn->endpoint->ep_description,
1155 if (endpoint == NULL) {
1159 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1161 * TODO: check if this is really needed
1163 * Or if we should fix this in our idl files.
1165 ep_prefix = "\\PIPE\\";
1169 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1172 if (pkt->u.bind_ack.secondary_address == NULL) {
1173 return NT_STATUS_NO_MEMORY;
1175 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1176 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1177 pkt->u.bind_ack.auth_info = data_blob_null;
1179 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1180 if (!NT_STATUS_IS_OK(status)) {
1181 return dcesrv_bind_nak(call, 0);
1184 if (auth->auth_finished) {
1185 return dcesrv_auth_reply(call);
1188 subreq = gensec_update_send(call, call->event_ctx,
1189 auth->gensec_security,
1190 call->in_auth_info.credentials);
1191 if (subreq == NULL) {
1192 return NT_STATUS_NO_MEMORY;
1194 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1196 return dcesrv_conn_auth_wait_setup(conn);
1199 static void dcesrv_bind_done(struct tevent_req *subreq)
1201 struct dcesrv_call_state *call =
1202 tevent_req_callback_data(subreq,
1203 struct dcesrv_call_state);
1204 struct dcesrv_connection *conn = call->conn;
1207 status = gensec_update_recv(subreq, call,
1208 &call->out_auth_info->credentials);
1209 TALLOC_FREE(subreq);
1211 status = dcesrv_auth_complete(call, status);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 status = dcesrv_bind_nak(call, 0);
1214 dcesrv_conn_auth_wait_finished(conn, status);
1218 status = dcesrv_auth_reply(call);
1219 dcesrv_conn_auth_wait_finished(conn, status);
1223 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1225 struct ncacn_packet *pkt = &call->ack_pkt;
1226 struct data_blob_list_item *rep = NULL;
1229 rep = talloc_zero(call, struct data_blob_list_item);
1231 return NT_STATUS_NO_MEMORY;
1234 status = ncacn_push_auth(&rep->blob, call, pkt,
1235 call->out_auth_info);
1236 if (!NT_STATUS_IS_OK(status)) {
1240 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1242 DLIST_ADD_END(call->replies, rep);
1243 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1245 if (call->conn->call_list && call->conn->call_list->replies) {
1246 if (call->conn->transport.report_output_data) {
1247 call->conn->transport.report_output_data(call->conn);
1251 return NT_STATUS_OK;
1255 static void dcesrv_auth3_done(struct tevent_req *subreq);
1258 handle a auth3 request
1260 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1262 struct dcesrv_connection *conn = call->conn;
1263 struct dcesrv_auth *auth = &call->conn->auth_state;
1264 struct tevent_req *subreq = NULL;
1267 if (!call->conn->allow_auth3) {
1268 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1271 if (call->conn->auth_state.auth_finished) {
1272 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1275 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1277 call->pkt.u.auth3.auth_info.length,
1278 0, /* required flags */
1279 DCERPC_PFC_FLAG_FIRST |
1280 DCERPC_PFC_FLAG_LAST |
1281 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1282 0x08 | /* this is not defined, but should be ignored */
1283 DCERPC_PFC_FLAG_CONC_MPX |
1284 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1285 DCERPC_PFC_FLAG_MAYBE |
1286 DCERPC_PFC_FLAG_OBJECT_UUID);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1291 /* handle the auth3 in the auth code */
1292 if (!dcesrv_auth_prepare_auth3(call)) {
1294 * we don't send a reply to a auth3 request,
1295 * except by a fault.
1297 * In anycase we mark the connection as
1300 call->conn->auth_state.auth_invalid = true;
1301 if (call->fault_code != 0) {
1302 return dcesrv_fault_disconnect(call, call->fault_code);
1305 return NT_STATUS_OK;
1308 subreq = gensec_update_send(call, call->event_ctx,
1309 auth->gensec_security,
1310 call->in_auth_info.credentials);
1311 if (subreq == NULL) {
1312 return NT_STATUS_NO_MEMORY;
1314 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1316 return dcesrv_conn_auth_wait_setup(conn);
1319 static void dcesrv_auth3_done(struct tevent_req *subreq)
1321 struct dcesrv_call_state *call =
1322 tevent_req_callback_data(subreq,
1323 struct dcesrv_call_state);
1324 struct dcesrv_connection *conn = call->conn;
1327 status = gensec_update_recv(subreq, call,
1328 &call->out_auth_info->credentials);
1329 TALLOC_FREE(subreq);
1331 status = dcesrv_auth_complete(call, status);
1332 if (!NT_STATUS_IS_OK(status)) {
1334 * we don't send a reply to a auth3 request,
1335 * except by a fault.
1337 * In anycase we mark the connection as
1340 call->conn->auth_state.auth_invalid = true;
1341 if (call->fault_code != 0) {
1342 status = dcesrv_fault_disconnect(call, call->fault_code);
1343 dcesrv_conn_auth_wait_finished(conn, status);
1347 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1352 * we don't send a reply to a auth3 request.
1355 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1360 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1361 const struct dcerpc_bind *b,
1362 const struct dcerpc_ctx_list *ctx,
1363 struct dcerpc_ack_ctx *ack,
1365 const struct ndr_syntax_id *supported_transfer)
1367 uint32_t if_version;
1368 struct dcesrv_connection_context *context;
1369 const struct dcesrv_interface *iface;
1372 const struct ndr_syntax_id *selected_transfer = NULL;
1377 return NT_STATUS_INTERNAL_ERROR;
1380 return NT_STATUS_INTERNAL_ERROR;
1382 if (ctx->num_transfer_syntaxes < 1) {
1383 return NT_STATUS_INTERNAL_ERROR;
1386 return NT_STATUS_INTERNAL_ERROR;
1388 if (supported_transfer == NULL) {
1389 return NT_STATUS_INTERNAL_ERROR;
1392 switch (ack->result) {
1393 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1394 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1396 * We is already completed.
1398 return NT_STATUS_OK;
1403 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1404 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1406 if_version = ctx->abstract_syntax.if_version;
1407 uuid = ctx->abstract_syntax.uuid;
1409 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1410 if (iface == NULL) {
1411 char *uuid_str = GUID_string(call, &uuid);
1412 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1413 talloc_free(uuid_str);
1415 * We report this only via ack->result
1417 return NT_STATUS_OK;
1420 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1421 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1423 if (validate_only) {
1425 * We report this only via ack->result
1427 return NT_STATUS_OK;
1430 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1432 * we only do NDR encoded dcerpc for now.
1434 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1435 supported_transfer);
1437 selected_transfer = supported_transfer;
1442 context = dcesrv_find_context(call->conn, ctx->context_id);
1443 if (context != NULL) {
1444 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1445 &ctx->abstract_syntax);
1447 return NT_STATUS_RPC_PROTOCOL_ERROR;
1450 if (selected_transfer != NULL) {
1451 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1454 return NT_STATUS_RPC_PROTOCOL_ERROR;
1457 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1458 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1459 ack->syntax = context->transfer_syntax;
1463 * We report this only via ack->result
1465 return NT_STATUS_OK;
1468 if (selected_transfer == NULL) {
1470 * We report this only via ack->result
1472 return NT_STATUS_OK;
1475 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1476 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1478 /* add this context to the list of available context_ids */
1479 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1480 if (context == NULL) {
1481 return NT_STATUS_NO_MEMORY;
1483 context->conn = call->conn;
1484 context->context_id = ctx->context_id;
1485 context->iface = iface;
1486 context->transfer_syntax = *selected_transfer;
1487 context->private_data = NULL;
1488 DLIST_ADD(call->conn->contexts, context);
1489 call->context = context;
1490 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1492 dcesrv_prepare_context_auth(call);
1495 * Multiplex is supported by default
1497 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1499 status = iface->bind(call, iface, if_version);
1500 call->context = NULL;
1501 if (!NT_STATUS_IS_OK(status)) {
1502 /* we don't want to trigger the iface->unbind() hook */
1503 context->iface = NULL;
1504 talloc_free(context);
1506 * We report this only via ack->result
1508 return NT_STATUS_OK;
1511 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1512 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1513 ack->syntax = context->transfer_syntax;
1514 return NT_STATUS_OK;
1517 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1518 const struct dcerpc_bind *b,
1519 struct dcerpc_ack_ctx *ack_ctx_list)
1523 bool validate_only = false;
1524 bool preferred_ndr32;
1527 * Try to negotiate one new presentation context,
1528 * using our preferred transfer syntax.
1530 for (i = 0; i < b->num_contexts; i++) {
1531 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1532 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1534 status = dcesrv_check_or_create_context(call, b, c, a,
1536 call->conn->preferred_transfer);
1537 if (!NT_STATUS_IS_OK(status)) {
1541 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1543 * We managed to negotiate one context.
1547 validate_only = true;
1551 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1552 call->conn->preferred_transfer);
1553 if (preferred_ndr32) {
1557 return NT_STATUS_OK;
1561 * Try to negotiate one new presentation context,
1562 * using NDR 32 as fallback.
1564 for (i = 0; i < b->num_contexts; i++) {
1565 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1566 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1568 status = dcesrv_check_or_create_context(call, b, c, a,
1570 &ndr_transfer_syntax_ndr);
1571 if (!NT_STATUS_IS_OK(status)) {
1575 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1577 * We managed to negotiate one context.
1581 validate_only = true;
1585 return NT_STATUS_OK;
1588 static void dcesrv_alter_done(struct tevent_req *subreq);
1591 handle a alter context request
1593 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1595 struct dcesrv_connection *conn = call->conn;
1597 bool auth_ok = false;
1598 struct ncacn_packet *pkt = &call->ack_pkt;
1599 uint32_t extra_flags = 0;
1600 struct dcesrv_auth *auth = &call->conn->auth_state;
1601 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1602 struct tevent_req *subreq = NULL;
1605 if (!call->conn->allow_alter) {
1606 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1609 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1611 call->pkt.u.alter.auth_info.length,
1612 0, /* required flags */
1613 DCERPC_PFC_FLAG_FIRST |
1614 DCERPC_PFC_FLAG_LAST |
1615 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1616 0x08 | /* this is not defined, but should be ignored */
1617 DCERPC_PFC_FLAG_CONC_MPX |
1618 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1619 DCERPC_PFC_FLAG_MAYBE |
1620 DCERPC_PFC_FLAG_OBJECT_UUID);
1621 if (!NT_STATUS_IS_OK(status)) {
1622 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1625 auth_ok = dcesrv_auth_alter(call);
1627 if (call->fault_code != 0) {
1628 return dcesrv_fault_disconnect(call, call->fault_code);
1632 if (call->pkt.u.alter.num_contexts < 1) {
1633 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1636 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1637 call->pkt.u.alter.num_contexts);
1638 if (ack_ctx_list == NULL) {
1639 return NT_STATUS_NO_MEMORY;
1643 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1644 * dcesrv_check_or_create_context()) and do some protocol validation
1645 * and set sane defaults.
1647 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1648 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1649 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1651 if (c->num_transfer_syntaxes == 0) {
1652 return dcesrv_fault_disconnect(call,
1653 DCERPC_NCA_S_PROTO_ERROR);
1656 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1657 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1661 * Try to negotiate one new presentation context.
1663 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1664 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1665 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1667 if (!NT_STATUS_IS_OK(status)) {
1671 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1672 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1673 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1674 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1677 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1678 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1681 /* handle any authentication that is being requested */
1683 if (call->in_auth_info.auth_type !=
1684 call->conn->auth_state.auth_type)
1686 return dcesrv_fault_disconnect(call,
1687 DCERPC_FAULT_SEC_PKG_ERROR);
1689 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1692 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1693 pkt->auth_length = 0;
1694 pkt->call_id = call->pkt.call_id;
1695 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1696 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1697 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1698 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1699 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1700 pkt->u.alter_resp.secondary_address = "";
1701 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1702 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1703 pkt->u.alter_resp.auth_info = data_blob_null;
1705 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1710 if (auth->auth_finished) {
1711 return dcesrv_auth_reply(call);
1714 subreq = gensec_update_send(call, call->event_ctx,
1715 auth->gensec_security,
1716 call->in_auth_info.credentials);
1717 if (subreq == NULL) {
1718 return NT_STATUS_NO_MEMORY;
1720 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1722 return dcesrv_conn_auth_wait_setup(conn);
1725 static void dcesrv_alter_done(struct tevent_req *subreq)
1727 struct dcesrv_call_state *call =
1728 tevent_req_callback_data(subreq,
1729 struct dcesrv_call_state);
1730 struct dcesrv_connection *conn = call->conn;
1733 status = gensec_update_recv(subreq, call,
1734 &call->out_auth_info->credentials);
1735 TALLOC_FREE(subreq);
1737 status = dcesrv_auth_complete(call, status);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1740 dcesrv_conn_auth_wait_finished(conn, status);
1744 status = dcesrv_auth_reply(call);
1745 dcesrv_conn_auth_wait_finished(conn, status);
1750 possibly save the call for inspection with ndrdump
1752 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1756 const char *dump_dir;
1757 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1761 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1763 call->context->iface->name,
1764 call->pkt.u.request.opnum,
1766 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1767 DEBUG(0,("RPC SAVED %s\n", fname));
1773 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1775 TALLOC_CTX *frame = talloc_stackframe();
1776 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1777 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1778 const struct dcerpc_sec_vt_pcontext pcontext = {
1779 .abstract_syntax = call->context->iface->syntax_id,
1780 .transfer_syntax = call->context->transfer_syntax,
1782 const struct dcerpc_sec_vt_header2 header2 =
1783 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1784 enum ndr_err_code ndr_err;
1785 struct dcerpc_sec_verification_trailer *vt = NULL;
1786 NTSTATUS status = NT_STATUS_OK;
1789 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1791 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1793 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1794 status = ndr_map_error2ntstatus(ndr_err);
1798 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1799 &pcontext, &header2);
1801 status = NT_STATUS_ACCESS_DENIED;
1810 handle a dcerpc request packet
1812 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1814 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1815 enum dcerpc_transport_t transport =
1816 dcerpc_binding_get_transport(endpoint->ep_description);
1817 struct ndr_pull *pull;
1820 if (!call->conn->allow_request) {
1821 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1824 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1825 if (call->conn->auth_state.gensec_security &&
1826 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1827 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1830 if (call->context == NULL) {
1831 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1832 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1835 switch (call->conn->auth_state.auth_level) {
1836 case DCERPC_AUTH_LEVEL_NONE:
1837 case DCERPC_AUTH_LEVEL_PACKET:
1838 case DCERPC_AUTH_LEVEL_INTEGRITY:
1839 case DCERPC_AUTH_LEVEL_PRIVACY:
1842 if (!call->context->allow_connect) {
1845 addr = tsocket_address_string(call->conn->remote_address,
1848 DEBUG(2, ("%s: restrict auth_level_connect access "
1849 "to [%s] with auth[type=0x%x,level=0x%x] "
1850 "on [%s] from [%s]\n",
1851 __func__, call->context->iface->name,
1852 call->conn->auth_state.auth_type,
1853 call->conn->auth_state.auth_level,
1854 derpc_transport_string_by_transport(transport),
1856 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1861 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1864 addr = tsocket_address_string(call->conn->remote_address, call);
1866 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1867 "to [%s] with auth[type=0x%x,level=0x%x] "
1868 "on [%s] from [%s]\n",
1870 call->context->min_auth_level,
1871 call->context->iface->name,
1872 call->conn->auth_state.auth_type,
1873 call->conn->auth_state.auth_level,
1874 derpc_transport_string_by_transport(transport),
1876 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1879 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1880 NT_STATUS_HAVE_NO_MEMORY(pull);
1882 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1884 call->ndr_pull = pull;
1886 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1887 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1890 status = dcesrv_check_verification_trailer(call);
1891 if (!NT_STATUS_IS_OK(status)) {
1892 uint32_t faultcode = DCERPC_FAULT_OTHER;
1893 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1894 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1896 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1897 nt_errstr(status)));
1898 return dcesrv_fault(call, faultcode);
1901 /* unravel the NDR for the packet */
1902 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1903 if (!NT_STATUS_IS_OK(status)) {
1904 uint8_t extra_flags = 0;
1905 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1906 /* we got an unknown call */
1907 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1908 call->pkt.u.request.opnum,
1909 call->context->iface->name));
1910 dcesrv_save_call(call, "unknown");
1911 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1913 dcesrv_save_call(call, "pullfail");
1915 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1918 if (pull->offset != pull->data_size) {
1919 dcesrv_save_call(call, "extrabytes");
1920 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1921 pull->data_size - pull->offset));
1924 /* call the dispatch function */
1925 status = call->context->iface->dispatch(call, call, call->r);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1928 call->context->iface->name,
1929 call->pkt.u.request.opnum,
1930 dcerpc_errstr(pull, call->fault_code)));
1931 return dcesrv_fault(call, call->fault_code);
1934 /* add the call to the pending list */
1935 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1937 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1938 return NT_STATUS_OK;
1941 return dcesrv_reply(call);
1946 remove the call from the right list when freed
1948 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1950 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1954 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1956 return conn->local_address;
1959 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1961 return conn->remote_address;
1965 process some input to a dcerpc endpoint server.
1967 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1968 struct ncacn_packet *pkt,
1972 struct dcesrv_call_state *call;
1973 struct dcesrv_call_state *existing = NULL;
1975 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1977 data_blob_free(&blob);
1979 return NT_STATUS_NO_MEMORY;
1981 call->conn = dce_conn;
1982 call->event_ctx = dce_conn->event_ctx;
1983 call->msg_ctx = dce_conn->msg_ctx;
1984 call->state_flags = call->conn->state_flags;
1985 call->time = timeval_current();
1986 call->list = DCESRV_LIST_NONE;
1988 talloc_steal(call, pkt);
1989 talloc_steal(call, blob.data);
1992 talloc_set_destructor(call, dcesrv_call_dequeue);
1994 if (call->conn->allow_bind) {
1996 * Only one bind is possible per connection
1998 call->conn->allow_bind = false;
1999 return dcesrv_bind(call);
2002 /* we have to check the signing here, before combining the
2004 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2005 if (!call->conn->allow_request) {
2006 return dcesrv_fault_disconnect(call,
2007 DCERPC_NCA_S_PROTO_ERROR);
2010 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2012 call->pkt.u.request.stub_and_verifier.length,
2013 0, /* required_flags */
2014 DCERPC_PFC_FLAG_FIRST |
2015 DCERPC_PFC_FLAG_LAST |
2016 DCERPC_PFC_FLAG_PENDING_CANCEL |
2017 0x08 | /* this is not defined, but should be ignored */
2018 DCERPC_PFC_FLAG_CONC_MPX |
2019 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2020 DCERPC_PFC_FLAG_MAYBE |
2021 DCERPC_PFC_FLAG_OBJECT_UUID);
2022 if (!NT_STATUS_IS_OK(status)) {
2023 return dcesrv_fault_disconnect(call,
2024 DCERPC_NCA_S_PROTO_ERROR);
2027 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2029 * We don't use dcesrv_fault_disconnect()
2030 * here, because we don't want to set
2031 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2033 * Note that we don't check against the negotiated
2034 * max_recv_frag, but a hard coded value.
2036 dcesrv_call_disconnect_after(call,
2037 "dcesrv_auth_request - frag_length too large");
2038 return dcesrv_fault(call,
2039 DCERPC_NCA_S_PROTO_ERROR);
2042 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2043 if (dce_conn->pending_call_list != NULL) {
2045 * concurrent requests are only allowed
2046 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2048 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2049 dcesrv_call_disconnect_after(call,
2050 "dcesrv_auth_request - "
2051 "existing pending call without CONN_MPX");
2052 return dcesrv_fault(call,
2053 DCERPC_NCA_S_PROTO_ERROR);
2056 /* only one request is possible in the fragmented list */
2057 if (dce_conn->incoming_fragmented_call_list != NULL) {
2058 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2060 * Without DCERPC_PFC_FLAG_CONC_MPX
2061 * we need to return the FAULT on the
2062 * already existing call.
2064 * This is important to get the
2065 * call_id and context_id right.
2068 call = dce_conn->incoming_fragmented_call_list;
2070 dcesrv_call_disconnect_after(call,
2071 "dcesrv_auth_request - "
2072 "existing fragmented call");
2073 return dcesrv_fault(call,
2074 DCERPC_NCA_S_PROTO_ERROR);
2076 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2077 return dcesrv_fault_disconnect(call,
2078 DCERPC_FAULT_NO_CALL_ACTIVE);
2080 call->context = dcesrv_find_context(call->conn,
2081 call->pkt.u.request.context_id);
2082 if (call->context == NULL) {
2083 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2084 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2087 const struct dcerpc_request *nr = &call->pkt.u.request;
2088 const struct dcerpc_request *er = NULL;
2091 existing = dcesrv_find_fragmented_call(dce_conn,
2093 if (existing == NULL) {
2094 dcesrv_call_disconnect_after(call,
2095 "dcesrv_auth_request - "
2096 "no existing fragmented call");
2097 return dcesrv_fault(call,
2098 DCERPC_NCA_S_PROTO_ERROR);
2100 er = &existing->pkt.u.request;
2102 if (call->pkt.ptype != existing->pkt.ptype) {
2103 /* trying to play silly buggers are we? */
2104 return dcesrv_fault_disconnect(existing,
2105 DCERPC_NCA_S_PROTO_ERROR);
2107 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2110 return dcesrv_fault_disconnect(existing,
2111 DCERPC_NCA_S_PROTO_ERROR);
2113 if (nr->context_id != er->context_id) {
2114 return dcesrv_fault_disconnect(existing,
2115 DCERPC_NCA_S_PROTO_ERROR);
2117 if (nr->opnum != er->opnum) {
2118 return dcesrv_fault_disconnect(existing,
2119 DCERPC_NCA_S_PROTO_ERROR);
2124 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2126 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2128 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2129 payload_offset += 16;
2132 ok = dcesrv_auth_pkt_pull(call, &blob,
2133 0, /* required_flags */
2134 DCERPC_PFC_FLAG_FIRST |
2135 DCERPC_PFC_FLAG_LAST |
2136 DCERPC_PFC_FLAG_PENDING_CANCEL |
2137 0x08 | /* this is not defined, but should be ignored */
2138 DCERPC_PFC_FLAG_CONC_MPX |
2139 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2140 DCERPC_PFC_FLAG_MAYBE |
2141 DCERPC_PFC_FLAG_OBJECT_UUID,
2143 &call->pkt.u.request.stub_and_verifier);
2146 * We don't use dcesrv_fault_disconnect()
2147 * here, because we don't want to set
2148 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2150 dcesrv_call_disconnect_after(call,
2151 "dcesrv_auth_request - failed");
2152 if (call->fault_code == 0) {
2153 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2155 return dcesrv_fault(call, call->fault_code);
2159 /* see if this is a continued packet */
2160 if (existing != NULL) {
2161 struct dcerpc_request *er = &existing->pkt.u.request;
2162 const struct dcerpc_request *nr = &call->pkt.u.request;
2168 * Up to 4 MByte are allowed by all fragments
2170 available = dce_conn->max_total_request_size;
2171 if (er->stub_and_verifier.length > available) {
2172 dcesrv_call_disconnect_after(existing,
2173 "dcesrv_auth_request - existing payload too large");
2174 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2176 available -= er->stub_and_verifier.length;
2177 if (nr->alloc_hint > available) {
2178 dcesrv_call_disconnect_after(existing,
2179 "dcesrv_auth_request - alloc hint too large");
2180 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2182 if (nr->stub_and_verifier.length > available) {
2183 dcesrv_call_disconnect_after(existing,
2184 "dcesrv_auth_request - new payload too large");
2185 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2187 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2188 /* allocate at least 1 byte */
2189 alloc_hint = MAX(alloc_hint, 1);
2190 alloc_size = er->stub_and_verifier.length +
2191 nr->stub_and_verifier.length;
2192 alloc_size = MAX(alloc_size, alloc_hint);
2194 er->stub_and_verifier.data =
2195 talloc_realloc(existing,
2196 er->stub_and_verifier.data,
2197 uint8_t, alloc_size);
2198 if (er->stub_and_verifier.data == NULL) {
2200 return dcesrv_fault_with_flags(existing,
2201 DCERPC_FAULT_OUT_OF_RESOURCES,
2202 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2204 memcpy(er->stub_and_verifier.data +
2205 er->stub_and_verifier.length,
2206 nr->stub_and_verifier.data,
2207 nr->stub_and_verifier.length);
2208 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2210 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2216 /* this may not be the last pdu in the chain - if its isn't then
2217 just put it on the incoming_fragmented_call_list and wait for the rest */
2218 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2219 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2221 * Up to 4 MByte are allowed by all fragments
2223 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2224 dcesrv_call_disconnect_after(call,
2225 "dcesrv_auth_request - initial alloc hint too large");
2226 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2228 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2229 return NT_STATUS_OK;
2232 /* This removes any fragments we may have had stashed away */
2233 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2235 switch (call->pkt.ptype) {
2236 case DCERPC_PKT_BIND:
2237 status = dcesrv_bind_nak(call,
2238 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2240 case DCERPC_PKT_AUTH3:
2241 status = dcesrv_auth3(call);
2243 case DCERPC_PKT_ALTER:
2244 status = dcesrv_alter(call);
2246 case DCERPC_PKT_REQUEST:
2247 status = dcesrv_request(call);
2249 case DCERPC_PKT_CO_CANCEL:
2250 case DCERPC_PKT_ORPHANED:
2252 * Window just ignores CO_CANCEL and ORPHANED,
2255 status = NT_STATUS_OK;
2258 case DCERPC_PKT_BIND_ACK:
2259 case DCERPC_PKT_BIND_NAK:
2260 case DCERPC_PKT_ALTER_RESP:
2261 case DCERPC_PKT_RESPONSE:
2262 case DCERPC_PKT_FAULT:
2263 case DCERPC_PKT_SHUTDOWN:
2265 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2269 /* if we are going to be sending a reply then add
2270 it to the list of pending calls. We add it to the end to keep the call
2271 list in the order we will answer */
2272 if (!NT_STATUS_IS_OK(status)) {
2279 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2280 struct loadparm_context *lp_ctx,
2281 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2284 struct dcesrv_context *dce_ctx;
2287 if (!endpoint_servers) {
2288 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2289 return NT_STATUS_INTERNAL_ERROR;
2292 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2293 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2295 if (uid_wrapper_enabled()) {
2296 setenv("UID_WRAPPER_MYUID", "1", 1);
2298 dce_ctx->initial_euid = geteuid();
2299 if (uid_wrapper_enabled()) {
2300 unsetenv("UID_WRAPPER_MYUID");
2303 dce_ctx->endpoint_list = NULL;
2304 dce_ctx->lp_ctx = lp_ctx;
2305 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2306 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2307 dce_ctx->broken_connections = NULL;
2309 for (i=0;endpoint_servers[i];i++) {
2310 const struct dcesrv_endpoint_server *ep_server;
2312 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2314 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2315 return NT_STATUS_INTERNAL_ERROR;
2318 status = ep_server->init_server(dce_ctx, ep_server);
2319 if (!NT_STATUS_IS_OK(status)) {
2320 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2321 nt_errstr(status)));
2326 *_dce_ctx = dce_ctx;
2327 return NT_STATUS_OK;
2330 /* the list of currently registered DCERPC endpoint servers.
2332 static struct ep_server {
2333 struct dcesrv_endpoint_server *ep_server;
2334 } *ep_servers = NULL;
2335 static int num_ep_servers;
2338 register a DCERPC endpoint server.
2340 The 'name' can be later used by other backends to find the operations
2341 structure for this backend.
2344 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2347 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2348 /* its already registered! */
2349 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2351 return NT_STATUS_OBJECT_NAME_COLLISION;
2354 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2356 smb_panic("out of memory in dcerpc_register");
2359 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2360 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2364 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2367 return NT_STATUS_OK;
2371 return the operations structure for a named backend of the specified type
2373 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2377 for (i=0;i<num_ep_servers;i++) {
2378 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2379 return ep_servers[i].ep_server;
2386 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2388 static bool initialized;
2389 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2390 STATIC_dcerpc_server_MODULES_PROTO;
2391 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2392 init_module_fn *shared_init;
2399 shared_init = load_samba_modules(NULL, "dcerpc_server");
2401 run_init_functions(NULL, static_init);
2402 run_init_functions(NULL, shared_init);
2404 talloc_free(shared_init);
2408 return the DCERPC module version, and the size of some critical types
2409 This can be used by endpoint server modules to either detect compilation errors, or provide
2410 multiple implementations for different smbd compilation options in one module
2412 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2414 static const struct dcesrv_critical_sizes critical_sizes = {
2415 DCERPC_MODULE_VERSION,
2416 sizeof(struct dcesrv_context),
2417 sizeof(struct dcesrv_endpoint),
2418 sizeof(struct dcesrv_endpoint_server),
2419 sizeof(struct dcesrv_interface),
2420 sizeof(struct dcesrv_if_list),
2421 sizeof(struct dcesrv_connection),
2422 sizeof(struct dcesrv_call_state),
2423 sizeof(struct dcesrv_auth),
2424 sizeof(struct dcesrv_handle)
2427 return &critical_sizes;
2430 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2432 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2433 struct stream_connection *srv_conn;
2434 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2435 struct stream_connection);
2437 dce_conn->wait_send = NULL;
2438 dce_conn->wait_recv = NULL;
2439 dce_conn->wait_private = NULL;
2441 dce_conn->allow_bind = false;
2442 dce_conn->allow_auth3 = false;
2443 dce_conn->allow_alter = false;
2444 dce_conn->allow_request = false;
2446 if (dce_conn->pending_call_list == NULL) {
2447 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2449 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2450 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2454 if (dce_conn->terminate != NULL) {
2458 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2460 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2461 if (dce_conn->terminate == NULL) {
2462 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2464 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2467 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2469 struct dcesrv_connection *cur, *next;
2471 next = dce_ctx->broken_connections;
2472 while (next != NULL) {
2476 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2477 struct dcesrv_connection_context *context_cur, *context_next;
2479 context_next = cur->contexts;
2480 while (context_next != NULL) {
2481 context_cur = context_next;
2482 context_next = context_cur->next;
2484 dcesrv_connection_context_destructor(context_cur);
2488 dcesrv_terminate_connection(cur, cur->terminate);
2492 /* We need this include to be able to compile on some plateforms
2493 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2495 * It has to be that deep because otherwise we have a conflict on
2496 * const struct dcesrv_interface declaration.
2497 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2498 * which conflict with the bind used before.
2500 #include "system/network.h"
2502 struct dcesrv_sock_reply_state {
2503 struct dcesrv_connection *dce_conn;
2504 struct dcesrv_call_state *call;
2508 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2509 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2511 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2513 struct dcesrv_call_state *call;
2515 call = dce_conn->call_list;
2516 if (!call || !call->replies) {
2520 while (call->replies) {
2521 struct data_blob_list_item *rep = call->replies;
2522 struct dcesrv_sock_reply_state *substate;
2523 struct tevent_req *subreq;
2525 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2527 dcesrv_terminate_connection(dce_conn, "no memory");
2531 substate->dce_conn = dce_conn;
2532 substate->call = NULL;
2534 DLIST_REMOVE(call->replies, rep);
2536 if (call->replies == NULL && call->terminate_reason == NULL) {
2537 substate->call = call;
2540 substate->iov.iov_base = (void *) rep->blob.data;
2541 substate->iov.iov_len = rep->blob.length;
2543 subreq = tstream_writev_queue_send(substate,
2544 dce_conn->event_ctx,
2546 dce_conn->send_queue,
2549 dcesrv_terminate_connection(dce_conn, "no memory");
2552 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2556 if (call->terminate_reason != NULL) {
2557 struct tevent_req *subreq;
2559 subreq = tevent_queue_wait_send(call,
2560 dce_conn->event_ctx,
2561 dce_conn->send_queue);
2563 dcesrv_terminate_connection(dce_conn, __location__);
2566 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2570 DLIST_REMOVE(call->conn->call_list, call);
2571 call->list = DCESRV_LIST_NONE;
2574 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2576 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2577 struct dcesrv_sock_reply_state);
2581 struct dcesrv_call_state *call = substate->call;
2583 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2584 TALLOC_FREE(subreq);
2586 status = map_nt_error_from_unix_common(sys_errno);
2587 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2591 talloc_free(substate);
2597 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2599 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2601 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2602 struct dcesrv_call_state);
2606 /* make sure we stop send queue before removing subreq */
2607 tevent_queue_stop(call->conn->send_queue);
2609 ok = tevent_queue_wait_recv(subreq);
2610 TALLOC_FREE(subreq);
2612 dcesrv_terminate_connection(call->conn, __location__);
2616 /* disconnect after 200 usecs */
2617 tv = timeval_current_ofs_usec(200);
2618 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2619 if (subreq == NULL) {
2620 dcesrv_terminate_connection(call->conn, __location__);
2623 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2627 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2629 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2630 struct dcesrv_call_state);
2633 ok = tevent_wakeup_recv(subreq);
2634 TALLOC_FREE(subreq);
2636 dcesrv_terminate_connection(call->conn, __location__);
2640 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2643 struct dcesrv_socket_context {
2644 const struct dcesrv_endpoint *endpoint;
2645 struct dcesrv_context *dcesrv_ctx;
2649 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2651 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2654 struct dcesrv_socket_context *dcesrv_sock =
2655 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2656 enum dcerpc_transport_t transport =
2657 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2658 struct dcesrv_connection *dcesrv_conn = NULL;
2660 struct tevent_req *subreq;
2661 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2663 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2665 if (!srv_conn->session_info) {
2666 status = auth_anonymous_session_info(srv_conn,
2668 &srv_conn->session_info);
2669 if (!NT_STATUS_IS_OK(status)) {
2670 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2671 nt_errstr(status)));
2672 stream_terminate_connection(srv_conn, nt_errstr(status));
2678 * This fills in dcesrv_conn->endpoint with the endpoint
2679 * associated with the socket. From this point on we know
2680 * which (group of) services we are handling, but not the
2681 * specific interface.
2684 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2686 dcesrv_sock->endpoint,
2687 srv_conn->session_info,
2688 srv_conn->event.ctx,
2690 srv_conn->server_id,
2691 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2693 if (!NT_STATUS_IS_OK(status)) {
2694 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2695 nt_errstr(status)));
2696 stream_terminate_connection(srv_conn, nt_errstr(status));
2700 dcesrv_conn->transport.private_data = srv_conn;
2701 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2703 TALLOC_FREE(srv_conn->event.fde);
2705 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2706 if (!dcesrv_conn->send_queue) {
2707 status = NT_STATUS_NO_MEMORY;
2708 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2709 nt_errstr(status)));
2710 stream_terminate_connection(srv_conn, nt_errstr(status));
2714 if (transport == NCACN_NP) {
2715 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2716 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2717 &srv_conn->tstream);
2719 ret = tstream_bsd_existing_socket(dcesrv_conn,
2720 socket_get_fd(srv_conn->socket),
2721 &dcesrv_conn->stream);
2723 status = map_nt_error_from_unix_common(errno);
2724 DEBUG(0, ("dcesrv_sock_accept: "
2725 "failed to setup tstream: %s\n",
2726 nt_errstr(status)));
2727 stream_terminate_connection(srv_conn, nt_errstr(status));
2730 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2733 dcesrv_conn->local_address = srv_conn->local_address;
2734 dcesrv_conn->remote_address = srv_conn->remote_address;
2736 if (transport == NCALRPC) {
2741 sock_fd = socket_get_fd(srv_conn->socket);
2742 if (sock_fd == -1) {
2743 stream_terminate_connection(
2744 srv_conn, "socket_get_fd failed\n");
2748 ret = getpeereid(sock_fd, &uid, &gid);
2750 status = map_nt_error_from_unix_common(errno);
2751 DEBUG(0, ("dcesrv_sock_accept: "
2752 "getpeereid() failed for NCALRPC: %s\n",
2753 nt_errstr(status)));
2754 stream_terminate_connection(srv_conn, nt_errstr(status));
2757 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2758 struct tsocket_address *r = NULL;
2760 ret = tsocket_address_unix_from_path(dcesrv_conn,
2761 AS_SYSTEM_MAGIC_PATH_TOKEN,
2764 status = map_nt_error_from_unix_common(errno);
2765 DEBUG(0, ("dcesrv_sock_accept: "
2766 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2767 nt_errstr(status)));
2768 stream_terminate_connection(srv_conn, nt_errstr(status));
2771 dcesrv_conn->remote_address = r;
2775 srv_conn->private_data = dcesrv_conn;
2777 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2778 dcesrv_conn->event_ctx,
2779 dcesrv_conn->stream);
2781 status = NT_STATUS_NO_MEMORY;
2782 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2783 nt_errstr(status)));
2784 stream_terminate_connection(srv_conn, nt_errstr(status));
2787 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2792 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2794 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2796 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2797 struct dcesrv_connection);
2798 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2799 struct ncacn_packet *pkt;
2803 if (dce_conn->terminate) {
2805 * if the current connection is broken
2806 * we need to clean it up before any other connection
2808 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2809 dcesrv_cleanup_broken_connections(dce_ctx);
2813 dcesrv_cleanup_broken_connections(dce_ctx);
2815 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2817 TALLOC_FREE(subreq);
2818 if (!NT_STATUS_IS_OK(status)) {
2819 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2823 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2830 * This is used to block the connection during
2831 * pending authentication.
2833 if (dce_conn->wait_send != NULL) {
2834 subreq = dce_conn->wait_send(dce_conn,
2835 dce_conn->event_ctx,
2836 dce_conn->wait_private);
2838 status = NT_STATUS_NO_MEMORY;
2839 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2842 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2846 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2847 dce_conn->event_ctx,
2850 status = NT_STATUS_NO_MEMORY;
2851 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2854 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2857 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2859 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2860 struct dcesrv_connection);
2861 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2864 if (dce_conn->terminate) {
2866 * if the current connection is broken
2867 * we need to clean it up before any other connection
2869 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2870 dcesrv_cleanup_broken_connections(dce_ctx);
2874 dcesrv_cleanup_broken_connections(dce_ctx);
2876 status = dce_conn->wait_recv(subreq);
2877 dce_conn->wait_send = NULL;
2878 dce_conn->wait_recv = NULL;
2879 dce_conn->wait_private = NULL;
2880 TALLOC_FREE(subreq);
2881 if (!NT_STATUS_IS_OK(status)) {
2882 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2886 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2887 dce_conn->event_ctx,
2890 status = NT_STATUS_NO_MEMORY;
2891 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2894 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2897 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2899 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2900 struct dcesrv_connection);
2901 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2904 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2906 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2907 struct dcesrv_connection);
2908 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2912 static const struct stream_server_ops dcesrv_stream_ops = {
2914 .accept_connection = dcesrv_sock_accept,
2915 .recv_handler = dcesrv_sock_recv,
2916 .send_handler = dcesrv_sock_send,
2919 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2920 struct loadparm_context *lp_ctx,
2921 struct dcesrv_endpoint *e,
2922 struct tevent_context *event_ctx,
2923 const struct model_ops *model_ops,
2924 void *process_context)
2926 struct dcesrv_socket_context *dcesrv_sock;
2929 const char *endpoint;
2931 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2932 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2934 /* remember the endpoint of this socket */
2935 dcesrv_sock->endpoint = e;
2936 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2938 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2940 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2941 model_ops, &dcesrv_stream_ops,
2942 "unix", endpoint, &port,
2943 lpcfg_socket_options(lp_ctx),
2944 dcesrv_sock, process_context);
2945 if (!NT_STATUS_IS_OK(status)) {
2946 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2947 endpoint, nt_errstr(status)));
2953 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2954 struct loadparm_context *lp_ctx,
2955 struct dcesrv_endpoint *e,
2956 struct tevent_context *event_ctx,
2957 const struct model_ops *model_ops,
2958 void *process_context)
2960 struct dcesrv_socket_context *dcesrv_sock;
2964 const char *endpoint;
2966 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2968 if (endpoint == NULL) {
2970 * No identifier specified: use DEFAULT.
2972 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2973 * no endpoint and let the epmapper worry about it.
2975 endpoint = "DEFAULT";
2976 status = dcerpc_binding_set_string_option(e->ep_description,
2979 if (!NT_STATUS_IS_OK(status)) {
2980 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2981 nt_errstr(status)));
2986 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2989 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2990 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2992 /* remember the endpoint of this socket */
2993 dcesrv_sock->endpoint = e;
2994 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2996 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2997 model_ops, &dcesrv_stream_ops,
2998 "unix", full_path, &port,
2999 lpcfg_socket_options(lp_ctx),
3000 dcesrv_sock, process_context);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3003 endpoint, full_path, nt_errstr(status)));
3008 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3009 struct loadparm_context *lp_ctx,
3010 struct dcesrv_endpoint *e,
3011 struct tevent_context *event_ctx,
3012 const struct model_ops *model_ops,
3013 void *process_context)
3015 struct dcesrv_socket_context *dcesrv_sock;
3017 const char *endpoint;
3019 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3020 if (endpoint == NULL) {
3021 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3022 return NT_STATUS_INVALID_PARAMETER;
3025 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3026 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3028 /* remember the endpoint of this socket */
3029 dcesrv_sock->endpoint = e;
3030 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3032 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3033 model_ops, &dcesrv_stream_ops,
3035 dcesrv_sock, process_context);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3038 endpoint, nt_errstr(status)));
3042 return NT_STATUS_OK;
3046 add a socket address to the list of events, one event per dcerpc endpoint
3048 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3049 struct dcesrv_endpoint *e,
3050 struct tevent_context *event_ctx,
3051 const struct model_ops *model_ops,
3052 const char *address,
3053 void *process_context)
3055 struct dcesrv_socket_context *dcesrv_sock;
3058 const char *endpoint;
3061 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3062 if (endpoint != NULL) {
3063 port = atoi(endpoint);
3066 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3067 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3069 /* remember the endpoint of this socket */
3070 dcesrv_sock->endpoint = e;
3071 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3073 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3074 model_ops, &dcesrv_stream_ops,
3075 "ip", address, &port,
3076 lpcfg_socket_options(dce_ctx->lp_ctx),
3077 dcesrv_sock, process_context);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 struct dcesrv_if_list *iface;
3080 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3082 for (iface = e->interface_list; iface; iface = iface->next) {
3083 DEBUGADD(0, ("%s ", iface->iface.name));
3085 DEBUGADD(0, ("failed - %s",
3086 nt_errstr(status)));
3090 snprintf(port_str, sizeof(port_str), "%u", port);
3092 status = dcerpc_binding_set_string_option(e->ep_description,
3093 "endpoint", port_str);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3096 port_str, nt_errstr(status)));
3099 struct dcesrv_if_list *iface;
3100 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3101 address, port_str));
3102 for (iface = e->interface_list; iface; iface = iface->next) {
3103 DEBUGADD(4, ("%s ", iface->iface.name));
3105 DEBUGADD(4, ("\n"));
3108 return NT_STATUS_OK;
3111 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3113 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3114 struct loadparm_context *lp_ctx,
3115 struct dcesrv_endpoint *e,
3116 struct tevent_context *event_ctx,
3117 const struct model_ops *model_ops,
3118 void *process_context)
3122 /* Add TCP/IP sockets */
3123 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3126 struct interface *ifaces;
3128 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3130 num_interfaces = iface_list_count(ifaces);
3131 for(i = 0; i < num_interfaces; i++) {
3132 const char *address = iface_list_n_ip(ifaces, i);
3133 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3136 NT_STATUS_NOT_OK_RETURN(status);
3141 size_t num_binds = 0;
3142 wcard = iface_list_wildcard(dce_ctx);
3143 NT_STATUS_HAVE_NO_MEMORY(wcard);
3144 for (i=0; wcard[i]; i++) {
3145 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3146 model_ops, wcard[i],
3148 if (NT_STATUS_IS_OK(status)) {
3153 if (num_binds == 0) {
3154 return NT_STATUS_INVALID_PARAMETER_MIX;
3158 return NT_STATUS_OK;
3161 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3162 struct loadparm_context *lp_ctx,
3163 struct dcesrv_endpoint *e,
3164 struct tevent_context *event_ctx,
3165 const struct model_ops *model_ops,
3166 void *process_context)
3168 enum dcerpc_transport_t transport =
3169 dcerpc_binding_get_transport(e->ep_description);
3171 switch (transport) {
3172 case NCACN_UNIX_STREAM:
3173 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3174 model_ops, process_context);
3177 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3178 model_ops, process_context);
3181 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3182 model_ops, process_context);
3185 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3186 model_ops, process_context);
3189 return NT_STATUS_NOT_SUPPORTED;
3195 * retrieve credentials from a dce_call
3197 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3199 return dce_call->conn->auth_state.session_info->credentials;
3203 * returns true if this is an authenticated call
3205 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3207 enum security_user_level level;
3208 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3209 return level >= SECURITY_USER;
3213 * retrieve account_name for a dce_call
3215 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3217 return dce_call->context->conn->auth_state.session_info->info->account_name;
3221 * retrieve session_info from a dce_call
3223 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3225 return dce_call->context->conn->auth_state.session_info;