2 Unix SMB/CIFS implementation.
4 server side dcerpc core code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
44 #include "../lib/util/tevent_ntstatus.h"
46 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
47 const struct dcerpc_bind *b,
48 struct dcerpc_ack_ctx *ack_ctx_list);
51 find an association group given a assoc_group_id
53 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
58 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
62 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
66 take a reference to an existing association group
68 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
69 struct dcesrv_context *dce_ctx,
72 struct dcesrv_assoc_group *assoc_group;
74 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
75 if (assoc_group == NULL) {
76 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
79 return talloc_reference(mem_ctx, assoc_group);
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
85 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
87 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
94 allocate a new association group
96 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
97 struct dcesrv_context *dce_ctx)
99 struct dcesrv_assoc_group *assoc_group;
102 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103 if (assoc_group == NULL) {
107 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
109 talloc_free(assoc_group);
110 DEBUG(0,(__location__ ": Out of association groups!\n"));
114 assoc_group->id = id;
115 assoc_group->dce_ctx = dce_ctx;
117 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
124 see if two endpoints match
126 static bool endpoints_match(const struct dcerpc_binding *ep1,
127 const struct dcerpc_binding *ep2)
129 enum dcerpc_transport_t t1;
130 enum dcerpc_transport_t t2;
134 t1 = dcerpc_binding_get_transport(ep1);
135 t2 = dcerpc_binding_get_transport(ep2);
137 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
138 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
148 if (strcasecmp(e1, e2) != 0) {
156 find an endpoint in the dcesrv_context
158 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
159 const struct dcerpc_binding *ep_description)
161 struct dcesrv_endpoint *ep;
162 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
163 if (endpoints_match(ep->ep_description, ep_description)) {
171 find a registered context_id from a bind or alter_context
173 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
176 struct dcesrv_connection_context *c;
177 for (c=conn->contexts;c;c=c->next) {
178 if (c->context_id == context_id) return c;
184 see if a uuid and if_version match to an interface
186 static bool interface_match(const struct dcesrv_interface *if1,
187 const struct dcesrv_interface *if2)
189 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
190 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
194 find the interface operations on any endpoint with this binding
196 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
197 struct dcerpc_binding *binding,
198 const struct dcesrv_interface *iface)
200 struct dcesrv_endpoint *ep;
201 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
202 if (endpoints_match(ep->ep_description, binding)) {
203 struct dcesrv_if_list *ifl;
204 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
205 if (interface_match(&(ifl->iface), iface)) {
206 return &(ifl->iface);
215 see if a uuid and if_version match to an interface
217 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
218 const struct GUID *uuid, uint32_t if_version)
220 return (iface->syntax_id.if_version == if_version &&
221 GUID_equal(&iface->syntax_id.uuid, uuid));
225 find the interface operations on an endpoint by uuid
227 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
228 const struct GUID *uuid, uint32_t if_version)
230 struct dcesrv_if_list *ifl;
231 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
232 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
233 return &(ifl->iface);
240 find the earlier parts of a fragmented call awaiting reassembily
242 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
244 struct dcesrv_call_state *c;
245 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
246 if (c->pkt.call_id == call_id) {
254 register an interface on an endpoint
256 An endpoint is one unix domain socket (for ncalrpc), one TCP port
257 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
259 Each endpoint can have many interfaces such as netlogon, lsa or
260 samr. Some have essentially the full set.
262 This is driven from the set of interfaces listed in each IDL file
263 via the PIDL generated *__op_init_server() functions.
265 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
267 const struct dcesrv_interface *iface,
268 const struct security_descriptor *sd)
270 struct dcesrv_endpoint *ep;
271 struct dcesrv_if_list *ifl;
272 struct dcerpc_binding *binding;
275 enum dcerpc_transport_t transport;
276 char *ep_string = NULL;
277 bool use_single_process = true;
278 const char *ep_process_string;
281 * If we are not using handles, there is no need for force
282 * this service into using a single process.
284 * However, due to the way we listen for RPC packets, we can
285 * only do this if we have a single service per pipe or TCP
286 * port, so we still force a single combined process for
289 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
290 use_single_process = false;
293 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
295 if (NT_STATUS_IS_ERR(status)) {
296 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
300 transport = dcerpc_binding_get_transport(binding);
301 if (transport == NCACN_IP_TCP) {
306 * First check if there is already a port specified, eg
307 * for epmapper on ncacn_ip_tcp:[135]
310 = dcerpc_binding_get_string_option(binding,
312 if (endpoint == NULL) {
313 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
314 "rpc server port", iface->name, 0);
317 * For RPC services that are not set to use a single
318 * process, we do not default to using the 'rpc server
319 * port' because that would cause a double-bind on
322 if (port == 0 && !use_single_process) {
323 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
326 snprintf(port_str, sizeof(port_str), "%u", port);
327 status = dcerpc_binding_set_string_option(binding,
330 if (!NT_STATUS_IS_OK(status)) {
337 /* see if the interface is already registered on the endpoint */
338 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
339 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
340 iface->name, ep_name));
341 return NT_STATUS_OBJECT_NAME_COLLISION;
344 /* check if this endpoint exists
346 ep = find_endpoint(dce_ctx, binding);
350 * We want a new port on ncacn_ip_tcp for NETLOGON, so
351 * it can be multi-process. Other processes can also
352 * listen on distinct ports, if they have one forced
353 * in the code above with eg 'rpc server port:drsuapi = 1027'
355 * If we have mulitiple endpoints on port 0, they each
356 * get an epemeral port (currently by walking up from
359 * Because one endpoint can only have one process
360 * model, we add a new IP_TCP endpoint for each model.
362 * This works in conjunction with the forced overwrite
363 * of ep->use_single_process below.
365 if (ep->use_single_process != use_single_process
366 && transport == NCACN_IP_TCP) {
371 if (ep == NULL || add_ep) {
372 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
374 return NT_STATUS_NO_MEMORY;
377 ep->ep_description = talloc_move(ep, &binding);
380 /* add mgmt interface */
381 ifl = talloc_zero(ep, struct dcesrv_if_list);
383 return NT_STATUS_NO_MEMORY;
386 ifl->iface = dcesrv_get_mgmt_interface();
388 DLIST_ADD(ep->interface_list, ifl);
392 * By default don't force into a single process, but if any
393 * interface on this endpoint on this service uses handles
394 * (most do), then we must force into single process mode
396 * By overwriting this each time a new interface is added to
397 * this endpoint, we end up with the most restrictive setting.
399 if (use_single_process) {
400 ep->use_single_process = true;
403 /* talloc a new interface list element */
404 ifl = talloc_zero(ep, struct dcesrv_if_list);
406 return NT_STATUS_NO_MEMORY;
409 /* copy the given interface struct to the one on the endpoints interface list */
410 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
412 /* if we have a security descriptor given,
413 * we should see if we can set it up on the endpoint
416 /* if there's currently no security descriptor given on the endpoint
419 if (ep->sd == NULL) {
420 ep->sd = security_descriptor_copy(ep, sd);
423 /* if now there's no security descriptor given on the endpoint
424 * something goes wrong, either we failed to copy the security descriptor
425 * or there was already one on the endpoint
427 if (ep->sd != NULL) {
428 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
429 " on endpoint '%s'\n",
430 iface->name, ep_name));
431 if (add_ep) free(ep);
433 return NT_STATUS_OBJECT_NAME_COLLISION;
437 /* finally add the interface on the endpoint */
438 DLIST_ADD(ep->interface_list, ifl);
440 /* if it's a new endpoint add it to the dcesrv_context */
442 DLIST_ADD(dce_ctx->endpoint_list, ep);
445 /* Re-get the string as we may have set a port */
446 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
448 if (use_single_process) {
449 ep_process_string = "single process required";
451 ep_process_string = "multi process compatible";
454 DBG_INFO("dcesrv_interface_register: interface '%s' "
455 "registered on endpoint '%s' (%s)\n",
456 iface->name, ep_string, ep_process_string);
457 TALLOC_FREE(ep_string);
462 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
463 DATA_BLOB *session_key)
465 if (auth->session_info == NULL) {
466 return NT_STATUS_NO_USER_SESSION_KEY;
469 if (auth->session_info->session_key.length == 0) {
470 return NT_STATUS_NO_USER_SESSION_KEY;
473 *session_key = auth->session_info->session_key;
477 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
478 DATA_BLOB *session_key)
480 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
481 return NT_STATUS_NO_USER_SESSION_KEY;
484 return dcesrv_session_info_session_key(auth, session_key);
487 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
488 DATA_BLOB *session_key)
490 return dcerpc_generic_session_key(NULL, session_key);
494 * Fetch the authentication session key if available.
496 * This is the key generated by a gensec authentication.
499 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
500 DATA_BLOB *session_key)
502 struct dcesrv_auth *auth = call->auth_state;
503 SMB_ASSERT(auth->auth_finished);
504 return dcesrv_session_info_session_key(auth, session_key);
508 * Fetch the transport session key if available.
509 * Typically this is the SMB session key
510 * or a fixed key for local transports.
512 * The key is always truncated to 16 bytes.
514 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
515 DATA_BLOB *session_key)
517 struct dcesrv_auth *auth = call->auth_state;
520 SMB_ASSERT(auth->auth_finished);
522 if (auth->session_key_fn == NULL) {
523 return NT_STATUS_NO_USER_SESSION_KEY;
526 status = auth->session_key_fn(auth, session_key);
527 if (!NT_STATUS_IS_OK(status)) {
531 session_key->length = MIN(session_key->length, 16);
536 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
538 const struct dcesrv_endpoint *ep = conn->endpoint;
539 enum dcerpc_transport_t transport =
540 dcerpc_binding_get_transport(ep->ep_description);
541 struct dcesrv_auth *auth = NULL;
543 auth = talloc_zero(conn, struct dcesrv_auth);
550 auth->session_key_fn = dcesrv_remote_session_key;
553 case NCACN_UNIX_STREAM:
554 auth->session_key_fn = dcesrv_local_fixed_session_key;
558 * All other's get a NULL pointer, which
559 * results in NT_STATUS_NO_USER_SESSION_KEY
568 connect to a dcerpc endpoint
570 static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
572 const struct dcesrv_endpoint *ep,
573 struct auth_session_info *session_info,
574 struct tevent_context *event_ctx,
575 struct imessaging_context *msg_ctx,
576 struct server_id server_id,
577 uint32_t state_flags,
578 struct dcesrv_connection **_p)
580 struct dcesrv_auth *auth = NULL;
581 struct dcesrv_connection *p;
584 return NT_STATUS_ACCESS_DENIED;
587 p = talloc_zero(mem_ctx, struct dcesrv_connection);
588 NT_STATUS_HAVE_NO_MEMORY(p);
590 p->dce_ctx = dce_ctx;
592 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
593 p->event_ctx = event_ctx;
594 p->msg_ctx = msg_ctx;
595 p->server_id = server_id;
596 p->state_flags = state_flags;
597 p->allow_bind = true;
598 p->max_recv_frag = 5840;
599 p->max_xmit_frag = 5840;
600 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
602 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
608 auth = dcesrv_auth_create(p);
611 return NT_STATUS_NO_MEMORY;
614 auth->session_info = talloc_reference(auth, session_info);
615 if (auth->session_info == NULL) {
617 return NT_STATUS_NO_MEMORY;
620 p->default_auth_state = auth;
623 * For now we only support NDR32.
625 p->preferred_transfer = &ndr_transfer_syntax_ndr;
632 move a call from an existing linked list to the specified list. This
633 prevents bugs where we forget to remove the call from a previous
636 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
637 enum dcesrv_call_list list)
639 switch (call->list) {
640 case DCESRV_LIST_NONE:
642 case DCESRV_LIST_CALL_LIST:
643 DLIST_REMOVE(call->conn->call_list, call);
645 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
646 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
648 case DCESRV_LIST_PENDING_CALL_LIST:
649 DLIST_REMOVE(call->conn->pending_call_list, call);
654 case DCESRV_LIST_NONE:
656 case DCESRV_LIST_CALL_LIST:
657 DLIST_ADD_END(call->conn->call_list, call);
659 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
660 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
662 case DCESRV_LIST_PENDING_CALL_LIST:
663 DLIST_ADD_END(call->conn->pending_call_list, call);
668 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
671 if (call->conn->terminate != NULL) {
675 call->conn->allow_bind = false;
676 call->conn->allow_alter = false;
678 call->conn->default_auth_state->auth_invalid = true;
680 call->terminate_reason = talloc_strdup(call, reason);
681 if (call->terminate_reason == NULL) {
682 call->terminate_reason = __location__;
687 return a dcerpc bind_nak
689 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
691 struct ncacn_packet pkt;
692 struct dcerpc_bind_nak_version version;
693 struct data_blob_list_item *rep;
695 static const uint8_t _pad[3] = { 0, };
698 * We add the call to the pending_call_list
699 * in order to defer the termination.
701 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
703 /* setup a bind_nak */
704 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
706 pkt.call_id = call->pkt.call_id;
707 pkt.ptype = DCERPC_PKT_BIND_NAK;
708 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
709 pkt.u.bind_nak.reject_reason = reason;
710 version.rpc_vers = 5;
711 version.rpc_vers_minor = 0;
712 pkt.u.bind_nak.num_versions = 1;
713 pkt.u.bind_nak.versions = &version;
714 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
716 rep = talloc_zero(call, struct data_blob_list_item);
718 return NT_STATUS_NO_MEMORY;
721 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
722 if (!NT_STATUS_IS_OK(status)) {
726 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
728 DLIST_ADD_END(call->replies, rep);
729 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
731 if (call->conn->call_list && call->conn->call_list->replies) {
732 if (call->conn->transport.report_output_data) {
733 call->conn->transport.report_output_data(call->conn);
740 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
744 * We add the call to the pending_call_list
745 * in order to defer the termination.
747 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
749 return dcesrv_fault_with_flags(call, fault_code,
750 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
753 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
755 DLIST_REMOVE(c->conn->contexts, c);
757 if (c->iface && c->iface->unbind) {
758 c->iface->unbind(c, c->iface);
765 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
767 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
768 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
769 enum dcerpc_transport_t transport =
770 dcerpc_binding_get_transport(endpoint->ep_description);
771 struct dcesrv_connection_context *context = dce_call->context;
772 const struct dcesrv_interface *iface = context->iface;
774 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
776 if (transport == NCALRPC) {
777 context->allow_connect = true;
782 * allow overwrite per interface
783 * allow dcerpc auth level connect:<interface>
785 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
786 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
787 "allow dcerpc auth level connect",
789 context->allow_connect);
792 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
793 const struct dcesrv_interface *iface)
796 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
797 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
799 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
803 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
804 const struct dcesrv_interface *iface)
806 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
810 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
811 const struct dcesrv_interface *iface)
813 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
814 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
815 enum dcerpc_transport_t transport =
816 dcerpc_binding_get_transport(endpoint->ep_description);
818 if (transport == NCALRPC) {
819 context->allow_connect = true;
824 * allow overwrite per interface
825 * allow dcerpc auth level connect:<interface>
827 context->allow_connect = false;
828 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
829 "allow dcerpc auth level connect",
831 context->allow_connect);
835 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
836 const struct dcesrv_interface *iface)
838 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
839 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
840 enum dcerpc_transport_t transport =
841 dcerpc_binding_get_transport(endpoint->ep_description);
843 if (transport == NCALRPC) {
844 context->allow_connect = true;
849 * allow overwrite per interface
850 * allow dcerpc auth level connect:<interface>
852 context->allow_connect = true;
853 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
854 "allow dcerpc auth level connect",
856 context->allow_connect);
860 struct dcesrv_conn_auth_wait_context {
861 struct tevent_req *req;
866 struct dcesrv_conn_auth_wait_state {
870 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
871 struct tevent_context *ev,
874 struct dcesrv_conn_auth_wait_context *auth_wait =
875 talloc_get_type_abort(private_data,
876 struct dcesrv_conn_auth_wait_context);
877 struct tevent_req *req = NULL;
878 struct dcesrv_conn_auth_wait_state *state = NULL;
880 req = tevent_req_create(mem_ctx, &state,
881 struct dcesrv_conn_auth_wait_state);
885 auth_wait->req = req;
887 tevent_req_defer_callback(req, ev);
889 if (!auth_wait->done) {
893 if (tevent_req_nterror(req, auth_wait->status)) {
894 return tevent_req_post(req, ev);
897 tevent_req_done(req);
898 return tevent_req_post(req, ev);
901 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
903 return tevent_req_simple_recv_ntstatus(req);
906 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
908 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
910 if (conn->wait_send != NULL) {
911 return NT_STATUS_INTERNAL_ERROR;
914 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
915 if (auth_wait == NULL) {
916 return NT_STATUS_NO_MEMORY;
919 conn->wait_private = auth_wait;
920 conn->wait_send = dcesrv_conn_auth_wait_send;
921 conn->wait_recv = dcesrv_conn_auth_wait_recv;
925 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
928 struct dcesrv_conn_auth_wait_context *auth_wait =
929 talloc_get_type_abort(conn->wait_private,
930 struct dcesrv_conn_auth_wait_context);
932 auth_wait->done = true;
933 auth_wait->status = status;
935 if (auth_wait->req == NULL) {
939 if (tevent_req_nterror(auth_wait->req, status)) {
943 tevent_req_done(auth_wait->req);
946 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
948 static void dcesrv_bind_done(struct tevent_req *subreq);
951 handle a bind request
953 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
955 struct dcesrv_connection *conn = call->conn;
956 struct ncacn_packet *pkt = &call->ack_pkt;
958 uint32_t extra_flags = 0;
959 uint16_t max_req = 0;
960 uint16_t max_rep = 0;
961 const char *ep_prefix = "";
962 const char *endpoint = NULL;
963 struct dcesrv_auth *auth = call->auth_state;
964 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
965 struct dcerpc_ack_ctx *ack_features = NULL;
966 struct tevent_req *subreq = NULL;
969 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
971 call->pkt.u.bind.auth_info.length,
972 0, /* required flags */
973 DCERPC_PFC_FLAG_FIRST |
974 DCERPC_PFC_FLAG_LAST |
975 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
976 0x08 | /* this is not defined, but should be ignored */
977 DCERPC_PFC_FLAG_CONC_MPX |
978 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
979 DCERPC_PFC_FLAG_MAYBE |
980 DCERPC_PFC_FLAG_OBJECT_UUID);
981 if (!NT_STATUS_IS_OK(status)) {
982 return dcesrv_bind_nak(call,
983 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
986 /* max_recv_frag and max_xmit_frag result always in the same value! */
987 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
988 call->pkt.u.bind.max_recv_frag);
990 * The values are between 2048 and 5840 tested against Windows 2012R2
991 * via ncacn_ip_tcp on port 135.
993 max_req = MAX(2048, max_req);
994 max_rep = MIN(max_req, call->conn->max_recv_frag);
995 /* They are truncated to an 8 byte boundary. */
998 /* max_recv_frag and max_xmit_frag result always in the same value! */
999 call->conn->max_recv_frag = max_rep;
1000 call->conn->max_xmit_frag = max_rep;
1003 if provided, check the assoc_group is valid
1005 if (call->pkt.u.bind.assoc_group_id != 0) {
1006 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
1007 call->conn->dce_ctx,
1008 call->pkt.u.bind.assoc_group_id);
1010 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
1011 call->conn->dce_ctx);
1015 * The NETLOGON server does not use handles and so
1016 * there is no need to support association groups, but
1017 * we need to give back a number regardless.
1019 * We have to do this when it is not run as a single process,
1020 * because then it can't see the other valid association
1021 * groups. We handle this genericly for all endpoints not
1022 * running in single process mode.
1024 * We know which endpoint we are on even before checking the
1025 * iface UUID, so for simplicity we enforce the same policy
1026 * for all interfaces on the endpoint.
1028 * This means that where NETLOGON
1029 * shares an endpoint (such as ncalrpc or of 'lsa over
1030 * netlogon' is set) we will still check association groups.
1034 if (call->conn->assoc_group == NULL &&
1035 !call->conn->endpoint->use_single_process) {
1036 call->conn->assoc_group
1037 = dcesrv_assoc_group_new(call->conn,
1038 call->conn->dce_ctx);
1040 if (call->conn->assoc_group == NULL) {
1041 return dcesrv_bind_nak(call, 0);
1044 if (call->pkt.u.bind.num_contexts < 1) {
1045 return dcesrv_bind_nak(call, 0);
1048 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1049 call->pkt.u.bind.num_contexts);
1050 if (ack_ctx_list == NULL) {
1051 return dcesrv_bind_nak(call, 0);
1055 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1056 * dcesrv_check_or_create_context()) and do some protocol validation
1057 * and set sane defaults.
1059 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1060 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1061 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1062 bool is_feature = false;
1063 uint64_t features = 0;
1065 if (c->num_transfer_syntaxes == 0) {
1066 return dcesrv_bind_nak(call, 0);
1069 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1070 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1073 * It's only treated as bind time feature request, if the first
1074 * transfer_syntax matches, all others are ignored.
1076 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1082 if (ack_features != NULL) {
1084 * Only one bind time feature context is allowed.
1086 return dcesrv_bind_nak(call, 0);
1090 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1091 a->reason.negotiate = 0;
1092 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1093 /* not supported yet */
1095 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1096 a->reason.negotiate |=
1097 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1100 call->conn->assoc_group->bind_time_features = a->reason.negotiate;
1104 * Try to negotiate one new presentation context.
1106 * Deep in here we locate the iface (by uuid) that the client
1107 * requested, from the list of interfaces on the
1108 * call->conn->endpoint, and call iface->bind() on that iface.
1110 * call->conn was set up at the accept() of the socket, and
1111 * call->conn->endpoint has a list of interfaces restricted to
1112 * this port or pipe.
1114 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1115 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1116 return dcesrv_bind_nak(call, 0);
1118 if (!NT_STATUS_IS_OK(status)) {
1123 * At this point we still don't know which interface (eg
1124 * netlogon, lsa, drsuapi) the caller requested in this bind!
1125 * The most recently added context is available as the first
1126 * element in the linked list at call->conn->contexts, that is
1127 * call->conn->contexts->iface, but they may not have
1128 * requested one at all!
1131 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1132 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1133 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1134 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1137 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1138 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1142 * After finding the interface and setting up the NDR
1143 * transport negotiation etc, handle any authentication that
1144 * is being requested.
1146 if (!dcesrv_auth_bind(call)) {
1148 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1150 * With DCERPC_AUTH_LEVEL_NONE, we get the
1151 * reject_reason in auth->auth_context_id.
1153 return dcesrv_bind_nak(call, auth->auth_context_id);
1157 * This must a be a temporary failure e.g. talloc or invalid
1158 * configuration, e.g. no machine account.
1160 return dcesrv_bind_nak(call,
1161 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1164 /* setup a bind_ack */
1165 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1166 pkt->auth_length = 0;
1167 pkt->call_id = call->pkt.call_id;
1168 pkt->ptype = DCERPC_PKT_BIND_ACK;
1169 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1170 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1171 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1172 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1174 endpoint = dcerpc_binding_get_string_option(
1175 call->conn->endpoint->ep_description,
1177 if (endpoint == NULL) {
1181 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1183 * TODO: check if this is really needed
1185 * Or if we should fix this in our idl files.
1187 ep_prefix = "\\PIPE\\";
1191 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1194 if (pkt->u.bind_ack.secondary_address == NULL) {
1195 return NT_STATUS_NO_MEMORY;
1197 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1198 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1199 pkt->u.bind_ack.auth_info = data_blob_null;
1201 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1202 if (!NT_STATUS_IS_OK(status)) {
1203 return dcesrv_bind_nak(call, 0);
1206 if (auth->auth_finished) {
1207 return dcesrv_auth_reply(call);
1210 subreq = gensec_update_send(call, call->event_ctx,
1211 auth->gensec_security,
1212 call->in_auth_info.credentials);
1213 if (subreq == NULL) {
1214 return NT_STATUS_NO_MEMORY;
1216 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1218 return dcesrv_conn_auth_wait_setup(conn);
1221 static void dcesrv_bind_done(struct tevent_req *subreq)
1223 struct dcesrv_call_state *call =
1224 tevent_req_callback_data(subreq,
1225 struct dcesrv_call_state);
1226 struct dcesrv_connection *conn = call->conn;
1229 status = gensec_update_recv(subreq, call,
1230 &call->out_auth_info->credentials);
1231 TALLOC_FREE(subreq);
1233 status = dcesrv_auth_complete(call, status);
1234 if (!NT_STATUS_IS_OK(status)) {
1235 status = dcesrv_bind_nak(call, 0);
1236 dcesrv_conn_auth_wait_finished(conn, status);
1240 status = dcesrv_auth_reply(call);
1241 dcesrv_conn_auth_wait_finished(conn, status);
1245 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1247 struct ncacn_packet *pkt = &call->ack_pkt;
1248 struct data_blob_list_item *rep = NULL;
1251 rep = talloc_zero(call, struct data_blob_list_item);
1253 return NT_STATUS_NO_MEMORY;
1256 status = ncacn_push_auth(&rep->blob, call, pkt,
1257 call->out_auth_info);
1258 if (!NT_STATUS_IS_OK(status)) {
1262 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1264 DLIST_ADD_END(call->replies, rep);
1265 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1267 if (call->conn->call_list && call->conn->call_list->replies) {
1268 if (call->conn->transport.report_output_data) {
1269 call->conn->transport.report_output_data(call->conn);
1273 return NT_STATUS_OK;
1277 static void dcesrv_auth3_done(struct tevent_req *subreq);
1280 handle a auth3 request
1282 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1284 struct dcesrv_connection *conn = call->conn;
1285 struct dcesrv_auth *auth = call->auth_state;
1286 struct tevent_req *subreq = NULL;
1289 if (!auth->auth_started) {
1290 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1293 if (auth->auth_finished) {
1294 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1297 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1299 call->pkt.u.auth3.auth_info.length,
1300 0, /* required flags */
1301 DCERPC_PFC_FLAG_FIRST |
1302 DCERPC_PFC_FLAG_LAST |
1303 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1304 0x08 | /* this is not defined, but should be ignored */
1305 DCERPC_PFC_FLAG_CONC_MPX |
1306 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1307 DCERPC_PFC_FLAG_MAYBE |
1308 DCERPC_PFC_FLAG_OBJECT_UUID);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1313 /* handle the auth3 in the auth code */
1314 if (!dcesrv_auth_prepare_auth3(call)) {
1316 * we don't send a reply to a auth3 request,
1317 * except by a fault.
1319 * In anycase we mark the connection as
1322 auth->auth_invalid = true;
1323 if (call->fault_code != 0) {
1324 return dcesrv_fault_disconnect(call, call->fault_code);
1327 return NT_STATUS_OK;
1330 subreq = gensec_update_send(call, call->event_ctx,
1331 auth->gensec_security,
1332 call->in_auth_info.credentials);
1333 if (subreq == NULL) {
1334 return NT_STATUS_NO_MEMORY;
1336 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1338 return dcesrv_conn_auth_wait_setup(conn);
1341 static void dcesrv_auth3_done(struct tevent_req *subreq)
1343 struct dcesrv_call_state *call =
1344 tevent_req_callback_data(subreq,
1345 struct dcesrv_call_state);
1346 struct dcesrv_connection *conn = call->conn;
1347 struct dcesrv_auth *auth = call->auth_state;
1350 status = gensec_update_recv(subreq, call,
1351 &call->out_auth_info->credentials);
1352 TALLOC_FREE(subreq);
1354 status = dcesrv_auth_complete(call, status);
1355 if (!NT_STATUS_IS_OK(status)) {
1357 * we don't send a reply to a auth3 request,
1358 * except by a fault.
1360 * In anycase we mark the connection as
1363 auth->auth_invalid = true;
1364 if (call->fault_code != 0) {
1365 status = dcesrv_fault_disconnect(call, call->fault_code);
1366 dcesrv_conn_auth_wait_finished(conn, status);
1370 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1375 * we don't send a reply to a auth3 request.
1378 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1383 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1384 const struct dcerpc_bind *b,
1385 const struct dcerpc_ctx_list *ctx,
1386 struct dcerpc_ack_ctx *ack,
1388 const struct ndr_syntax_id *supported_transfer)
1390 uint32_t if_version;
1391 struct dcesrv_connection_context *context;
1392 const struct dcesrv_interface *iface;
1395 const struct ndr_syntax_id *selected_transfer = NULL;
1400 return NT_STATUS_INTERNAL_ERROR;
1403 return NT_STATUS_INTERNAL_ERROR;
1405 if (ctx->num_transfer_syntaxes < 1) {
1406 return NT_STATUS_INTERNAL_ERROR;
1409 return NT_STATUS_INTERNAL_ERROR;
1411 if (supported_transfer == NULL) {
1412 return NT_STATUS_INTERNAL_ERROR;
1415 switch (ack->result) {
1416 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1417 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1419 * We is already completed.
1421 return NT_STATUS_OK;
1426 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1427 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1429 if_version = ctx->abstract_syntax.if_version;
1430 uuid = ctx->abstract_syntax.uuid;
1432 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1433 if (iface == NULL) {
1434 char *uuid_str = GUID_string(call, &uuid);
1435 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1436 talloc_free(uuid_str);
1438 * We report this only via ack->result
1440 return NT_STATUS_OK;
1443 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1444 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1446 if (validate_only) {
1448 * We report this only via ack->result
1450 return NT_STATUS_OK;
1453 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1455 * we only do NDR encoded dcerpc for now.
1457 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1458 supported_transfer);
1460 selected_transfer = supported_transfer;
1465 context = dcesrv_find_context(call->conn, ctx->context_id);
1466 if (context != NULL) {
1467 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1468 &ctx->abstract_syntax);
1470 return NT_STATUS_RPC_PROTOCOL_ERROR;
1473 if (selected_transfer != NULL) {
1474 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1477 return NT_STATUS_RPC_PROTOCOL_ERROR;
1480 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1481 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1482 ack->syntax = context->transfer_syntax;
1486 * We report this only via ack->result
1488 return NT_STATUS_OK;
1491 if (selected_transfer == NULL) {
1493 * We report this only via ack->result
1495 return NT_STATUS_OK;
1498 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1499 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1501 /* add this context to the list of available context_ids */
1502 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1503 if (context == NULL) {
1504 return NT_STATUS_NO_MEMORY;
1506 context->conn = call->conn;
1507 context->context_id = ctx->context_id;
1508 context->iface = iface;
1509 context->transfer_syntax = *selected_transfer;
1510 DLIST_ADD(call->conn->contexts, context);
1511 call->context = context;
1512 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1514 dcesrv_prepare_context_auth(call);
1517 * Multiplex is supported by default
1519 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1521 status = iface->bind(context, iface);
1522 call->context = NULL;
1523 if (!NT_STATUS_IS_OK(status)) {
1524 /* we don't want to trigger the iface->unbind() hook */
1525 context->iface = NULL;
1526 talloc_free(context);
1528 * We report this only via ack->result
1530 return NT_STATUS_OK;
1533 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1534 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1535 ack->syntax = context->transfer_syntax;
1536 return NT_STATUS_OK;
1539 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1540 const struct dcerpc_bind *b,
1541 struct dcerpc_ack_ctx *ack_ctx_list)
1545 bool validate_only = false;
1546 bool preferred_ndr32;
1549 * Try to negotiate one new presentation context,
1550 * using our preferred transfer syntax.
1552 for (i = 0; i < b->num_contexts; i++) {
1553 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1554 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1556 status = dcesrv_check_or_create_context(call, b, c, a,
1558 call->conn->preferred_transfer);
1559 if (!NT_STATUS_IS_OK(status)) {
1563 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1565 * We managed to negotiate one context.
1569 validate_only = true;
1573 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1574 call->conn->preferred_transfer);
1575 if (preferred_ndr32) {
1579 return NT_STATUS_OK;
1583 * Try to negotiate one new presentation context,
1584 * using NDR 32 as fallback.
1586 for (i = 0; i < b->num_contexts; i++) {
1587 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1588 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1590 status = dcesrv_check_or_create_context(call, b, c, a,
1592 &ndr_transfer_syntax_ndr);
1593 if (!NT_STATUS_IS_OK(status)) {
1597 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1599 * We managed to negotiate one context.
1603 validate_only = true;
1607 return NT_STATUS_OK;
1610 static void dcesrv_alter_done(struct tevent_req *subreq);
1613 handle a alter context request
1615 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1617 struct dcesrv_connection *conn = call->conn;
1619 bool auth_ok = false;
1620 struct ncacn_packet *pkt = &call->ack_pkt;
1621 uint32_t extra_flags = 0;
1622 struct dcesrv_auth *auth = call->auth_state;
1623 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1624 struct tevent_req *subreq = NULL;
1627 if (!call->conn->allow_alter) {
1628 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1631 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1633 call->pkt.u.alter.auth_info.length,
1634 0, /* required flags */
1635 DCERPC_PFC_FLAG_FIRST |
1636 DCERPC_PFC_FLAG_LAST |
1637 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1638 0x08 | /* this is not defined, but should be ignored */
1639 DCERPC_PFC_FLAG_CONC_MPX |
1640 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1641 DCERPC_PFC_FLAG_MAYBE |
1642 DCERPC_PFC_FLAG_OBJECT_UUID);
1643 if (!NT_STATUS_IS_OK(status)) {
1644 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1647 auth_ok = dcesrv_auth_alter(call);
1649 if (call->fault_code != 0) {
1650 return dcesrv_fault_disconnect(call, call->fault_code);
1654 if (call->pkt.u.alter.num_contexts < 1) {
1655 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1658 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1659 call->pkt.u.alter.num_contexts);
1660 if (ack_ctx_list == NULL) {
1661 return NT_STATUS_NO_MEMORY;
1665 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1666 * dcesrv_check_or_create_context()) and do some protocol validation
1667 * and set sane defaults.
1669 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1670 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1671 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1673 if (c->num_transfer_syntaxes == 0) {
1674 return dcesrv_fault_disconnect(call,
1675 DCERPC_NCA_S_PROTO_ERROR);
1678 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1679 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1683 * Try to negotiate one new presentation context.
1685 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1686 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1687 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1689 if (!NT_STATUS_IS_OK(status)) {
1693 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1694 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1695 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1696 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1699 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1700 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1703 /* handle any authentication that is being requested */
1705 if (call->in_auth_info.auth_type != auth->auth_type) {
1706 return dcesrv_fault_disconnect(call,
1707 DCERPC_FAULT_SEC_PKG_ERROR);
1709 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1712 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1713 pkt->auth_length = 0;
1714 pkt->call_id = call->pkt.call_id;
1715 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1716 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1717 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1718 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1719 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1720 pkt->u.alter_resp.secondary_address = "";
1721 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1722 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1723 pkt->u.alter_resp.auth_info = data_blob_null;
1725 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1726 if (!NT_STATUS_IS_OK(status)) {
1727 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1730 if (auth->auth_finished) {
1731 return dcesrv_auth_reply(call);
1734 subreq = gensec_update_send(call, call->event_ctx,
1735 auth->gensec_security,
1736 call->in_auth_info.credentials);
1737 if (subreq == NULL) {
1738 return NT_STATUS_NO_MEMORY;
1740 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1742 return dcesrv_conn_auth_wait_setup(conn);
1745 static void dcesrv_alter_done(struct tevent_req *subreq)
1747 struct dcesrv_call_state *call =
1748 tevent_req_callback_data(subreq,
1749 struct dcesrv_call_state);
1750 struct dcesrv_connection *conn = call->conn;
1753 status = gensec_update_recv(subreq, call,
1754 &call->out_auth_info->credentials);
1755 TALLOC_FREE(subreq);
1757 status = dcesrv_auth_complete(call, status);
1758 if (!NT_STATUS_IS_OK(status)) {
1759 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1760 dcesrv_conn_auth_wait_finished(conn, status);
1764 status = dcesrv_auth_reply(call);
1765 dcesrv_conn_auth_wait_finished(conn, status);
1770 possibly save the call for inspection with ndrdump
1772 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1776 const char *dump_dir;
1777 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1781 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1783 call->context->iface->name,
1784 call->pkt.u.request.opnum,
1786 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1787 DEBUG(0,("RPC SAVED %s\n", fname));
1793 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1795 TALLOC_CTX *frame = talloc_stackframe();
1796 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1797 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1798 const struct dcerpc_sec_vt_pcontext pcontext = {
1799 .abstract_syntax = call->context->iface->syntax_id,
1800 .transfer_syntax = call->context->transfer_syntax,
1802 const struct dcerpc_sec_vt_header2 header2 =
1803 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1804 enum ndr_err_code ndr_err;
1805 struct dcerpc_sec_verification_trailer *vt = NULL;
1806 NTSTATUS status = NT_STATUS_OK;
1809 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1811 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1813 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1814 status = ndr_map_error2ntstatus(ndr_err);
1818 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1819 &pcontext, &header2);
1821 status = NT_STATUS_ACCESS_DENIED;
1830 handle a dcerpc request packet
1832 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1834 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1835 struct dcesrv_auth *auth = call->auth_state;
1836 enum dcerpc_transport_t transport =
1837 dcerpc_binding_get_transport(endpoint->ep_description);
1838 struct ndr_pull *pull;
1841 if (!auth->auth_finished) {
1842 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1845 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1846 if (auth->gensec_security != NULL &&
1847 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1848 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1851 if (call->context == NULL) {
1852 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1853 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1856 switch (auth->auth_level) {
1857 case DCERPC_AUTH_LEVEL_NONE:
1858 case DCERPC_AUTH_LEVEL_PACKET:
1859 case DCERPC_AUTH_LEVEL_INTEGRITY:
1860 case DCERPC_AUTH_LEVEL_PRIVACY:
1863 if (!call->context->allow_connect) {
1866 addr = tsocket_address_string(call->conn->remote_address,
1869 DEBUG(2, ("%s: restrict auth_level_connect access "
1870 "to [%s] with auth[type=0x%x,level=0x%x] "
1871 "on [%s] from [%s]\n",
1872 __func__, call->context->iface->name,
1875 derpc_transport_string_by_transport(transport),
1877 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1882 if (auth->auth_level < call->context->min_auth_level) {
1885 addr = tsocket_address_string(call->conn->remote_address, call);
1887 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1888 "to [%s] with auth[type=0x%x,level=0x%x] "
1889 "on [%s] from [%s]\n",
1891 call->context->min_auth_level,
1892 call->context->iface->name,
1895 derpc_transport_string_by_transport(transport),
1897 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1900 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1901 NT_STATUS_HAVE_NO_MEMORY(pull);
1903 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1905 call->ndr_pull = pull;
1907 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1908 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1911 status = dcesrv_check_verification_trailer(call);
1912 if (!NT_STATUS_IS_OK(status)) {
1913 uint32_t faultcode = DCERPC_FAULT_OTHER;
1914 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1915 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1917 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1918 nt_errstr(status)));
1919 return dcesrv_fault(call, faultcode);
1922 /* unravel the NDR for the packet */
1923 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1924 if (!NT_STATUS_IS_OK(status)) {
1925 uint8_t extra_flags = 0;
1926 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1927 /* we got an unknown call */
1928 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1929 call->pkt.u.request.opnum,
1930 call->context->iface->name));
1931 dcesrv_save_call(call, "unknown");
1932 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1934 dcesrv_save_call(call, "pullfail");
1936 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1939 if (pull->offset != pull->data_size) {
1940 dcesrv_save_call(call, "extrabytes");
1941 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1942 pull->data_size - pull->offset));
1945 /* call the dispatch function */
1946 status = call->context->iface->dispatch(call, call, call->r);
1947 if (!NT_STATUS_IS_OK(status)) {
1948 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1949 call->context->iface->name,
1950 call->pkt.u.request.opnum,
1951 dcerpc_errstr(pull, call->fault_code)));
1952 return dcesrv_fault(call, call->fault_code);
1955 /* add the call to the pending list */
1956 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1958 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1959 return NT_STATUS_OK;
1962 return dcesrv_reply(call);
1967 remove the call from the right list when freed
1969 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1971 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1975 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1977 return conn->local_address;
1980 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1982 return conn->remote_address;
1986 process some input to a dcerpc endpoint server.
1988 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1989 struct ncacn_packet *pkt,
1993 struct dcesrv_call_state *call;
1994 struct dcesrv_call_state *existing = NULL;
1996 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1998 data_blob_free(&blob);
2000 return NT_STATUS_NO_MEMORY;
2002 call->conn = dce_conn;
2003 call->event_ctx = dce_conn->event_ctx;
2004 call->msg_ctx = dce_conn->msg_ctx;
2005 call->state_flags = call->conn->state_flags;
2006 call->time = timeval_current();
2007 call->list = DCESRV_LIST_NONE;
2009 talloc_steal(call, pkt);
2010 talloc_steal(call, blob.data);
2013 call->auth_state = dce_conn->default_auth_state;
2015 talloc_set_destructor(call, dcesrv_call_dequeue);
2017 if (call->conn->allow_bind) {
2019 * Only one bind is possible per connection
2021 call->conn->allow_bind = false;
2022 return dcesrv_bind(call);
2025 /* we have to check the signing here, before combining the
2027 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2028 if (!call->auth_state->auth_finished) {
2029 return dcesrv_fault_disconnect(call,
2030 DCERPC_NCA_S_PROTO_ERROR);
2033 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2035 call->pkt.u.request.stub_and_verifier.length,
2036 0, /* required_flags */
2037 DCERPC_PFC_FLAG_FIRST |
2038 DCERPC_PFC_FLAG_LAST |
2039 DCERPC_PFC_FLAG_PENDING_CANCEL |
2040 0x08 | /* this is not defined, but should be ignored */
2041 DCERPC_PFC_FLAG_CONC_MPX |
2042 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2043 DCERPC_PFC_FLAG_MAYBE |
2044 DCERPC_PFC_FLAG_OBJECT_UUID);
2045 if (!NT_STATUS_IS_OK(status)) {
2046 return dcesrv_fault_disconnect(call,
2047 DCERPC_NCA_S_PROTO_ERROR);
2050 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2052 * We don't use dcesrv_fault_disconnect()
2053 * here, because we don't want to set
2054 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2056 * Note that we don't check against the negotiated
2057 * max_recv_frag, but a hard coded value.
2059 dcesrv_call_disconnect_after(call,
2060 "dcesrv_auth_request - frag_length too large");
2061 return dcesrv_fault(call,
2062 DCERPC_NCA_S_PROTO_ERROR);
2065 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2066 if (dce_conn->pending_call_list != NULL) {
2068 * concurrent requests are only allowed
2069 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2071 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2072 dcesrv_call_disconnect_after(call,
2073 "dcesrv_auth_request - "
2074 "existing pending call without CONN_MPX");
2075 return dcesrv_fault(call,
2076 DCERPC_NCA_S_PROTO_ERROR);
2079 /* only one request is possible in the fragmented list */
2080 if (dce_conn->incoming_fragmented_call_list != NULL) {
2081 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2083 * Without DCERPC_PFC_FLAG_CONC_MPX
2084 * we need to return the FAULT on the
2085 * already existing call.
2087 * This is important to get the
2088 * call_id and context_id right.
2091 call = dce_conn->incoming_fragmented_call_list;
2093 dcesrv_call_disconnect_after(call,
2094 "dcesrv_auth_request - "
2095 "existing fragmented call");
2096 return dcesrv_fault(call,
2097 DCERPC_NCA_S_PROTO_ERROR);
2099 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2100 return dcesrv_fault_disconnect(call,
2101 DCERPC_FAULT_NO_CALL_ACTIVE);
2103 call->context = dcesrv_find_context(call->conn,
2104 call->pkt.u.request.context_id);
2105 if (call->context == NULL) {
2106 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2107 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2110 const struct dcerpc_request *nr = &call->pkt.u.request;
2111 const struct dcerpc_request *er = NULL;
2114 existing = dcesrv_find_fragmented_call(dce_conn,
2116 if (existing == NULL) {
2117 dcesrv_call_disconnect_after(call,
2118 "dcesrv_auth_request - "
2119 "no existing fragmented call");
2120 return dcesrv_fault(call,
2121 DCERPC_NCA_S_PROTO_ERROR);
2123 er = &existing->pkt.u.request;
2125 if (call->pkt.ptype != existing->pkt.ptype) {
2126 /* trying to play silly buggers are we? */
2127 return dcesrv_fault_disconnect(existing,
2128 DCERPC_NCA_S_PROTO_ERROR);
2130 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2133 return dcesrv_fault_disconnect(existing,
2134 DCERPC_NCA_S_PROTO_ERROR);
2136 if (nr->context_id != er->context_id) {
2137 return dcesrv_fault_disconnect(existing,
2138 DCERPC_NCA_S_PROTO_ERROR);
2140 if (nr->opnum != er->opnum) {
2141 return dcesrv_fault_disconnect(existing,
2142 DCERPC_NCA_S_PROTO_ERROR);
2147 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2149 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2151 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2152 payload_offset += 16;
2155 ok = dcesrv_auth_pkt_pull(call, &blob,
2156 0, /* required_flags */
2157 DCERPC_PFC_FLAG_FIRST |
2158 DCERPC_PFC_FLAG_LAST |
2159 DCERPC_PFC_FLAG_PENDING_CANCEL |
2160 0x08 | /* this is not defined, but should be ignored */
2161 DCERPC_PFC_FLAG_CONC_MPX |
2162 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2163 DCERPC_PFC_FLAG_MAYBE |
2164 DCERPC_PFC_FLAG_OBJECT_UUID,
2166 &call->pkt.u.request.stub_and_verifier);
2169 * We don't use dcesrv_fault_disconnect()
2170 * here, because we don't want to set
2171 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2173 dcesrv_call_disconnect_after(call,
2174 "dcesrv_auth_request - failed");
2175 if (call->fault_code == 0) {
2176 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2178 return dcesrv_fault(call, call->fault_code);
2182 /* see if this is a continued packet */
2183 if (existing != NULL) {
2184 struct dcerpc_request *er = &existing->pkt.u.request;
2185 const struct dcerpc_request *nr = &call->pkt.u.request;
2191 * Up to 4 MByte are allowed by all fragments
2193 available = dce_conn->max_total_request_size;
2194 if (er->stub_and_verifier.length > available) {
2195 dcesrv_call_disconnect_after(existing,
2196 "dcesrv_auth_request - existing payload too large");
2197 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2199 available -= er->stub_and_verifier.length;
2200 if (nr->alloc_hint > available) {
2201 dcesrv_call_disconnect_after(existing,
2202 "dcesrv_auth_request - alloc hint too large");
2203 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2205 if (nr->stub_and_verifier.length > available) {
2206 dcesrv_call_disconnect_after(existing,
2207 "dcesrv_auth_request - new payload too large");
2208 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2210 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2211 /* allocate at least 1 byte */
2212 alloc_hint = MAX(alloc_hint, 1);
2213 alloc_size = er->stub_and_verifier.length +
2214 nr->stub_and_verifier.length;
2215 alloc_size = MAX(alloc_size, alloc_hint);
2217 er->stub_and_verifier.data =
2218 talloc_realloc(existing,
2219 er->stub_and_verifier.data,
2220 uint8_t, alloc_size);
2221 if (er->stub_and_verifier.data == NULL) {
2223 return dcesrv_fault_with_flags(existing,
2224 DCERPC_FAULT_OUT_OF_RESOURCES,
2225 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2227 memcpy(er->stub_and_verifier.data +
2228 er->stub_and_verifier.length,
2229 nr->stub_and_verifier.data,
2230 nr->stub_and_verifier.length);
2231 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2233 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2239 /* this may not be the last pdu in the chain - if its isn't then
2240 just put it on the incoming_fragmented_call_list and wait for the rest */
2241 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2242 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2244 * Up to 4 MByte are allowed by all fragments
2246 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2247 dcesrv_call_disconnect_after(call,
2248 "dcesrv_auth_request - initial alloc hint too large");
2249 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2251 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2252 return NT_STATUS_OK;
2255 /* This removes any fragments we may have had stashed away */
2256 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2258 switch (call->pkt.ptype) {
2259 case DCERPC_PKT_BIND:
2260 status = dcesrv_bind_nak(call,
2261 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2263 case DCERPC_PKT_AUTH3:
2264 status = dcesrv_auth3(call);
2266 case DCERPC_PKT_ALTER:
2267 status = dcesrv_alter(call);
2269 case DCERPC_PKT_REQUEST:
2270 status = dcesrv_request(call);
2272 case DCERPC_PKT_CO_CANCEL:
2273 case DCERPC_PKT_ORPHANED:
2275 * Window just ignores CO_CANCEL and ORPHANED,
2278 status = NT_STATUS_OK;
2281 case DCERPC_PKT_BIND_ACK:
2282 case DCERPC_PKT_BIND_NAK:
2283 case DCERPC_PKT_ALTER_RESP:
2284 case DCERPC_PKT_RESPONSE:
2285 case DCERPC_PKT_FAULT:
2286 case DCERPC_PKT_SHUTDOWN:
2288 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2292 /* if we are going to be sending a reply then add
2293 it to the list of pending calls. We add it to the end to keep the call
2294 list in the order we will answer */
2295 if (!NT_STATUS_IS_OK(status)) {
2302 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2303 struct loadparm_context *lp_ctx,
2304 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2307 struct dcesrv_context *dce_ctx;
2310 if (!endpoint_servers) {
2311 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2312 return NT_STATUS_INTERNAL_ERROR;
2315 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2316 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2318 if (uid_wrapper_enabled()) {
2319 setenv("UID_WRAPPER_MYUID", "1", 1);
2321 dce_ctx->initial_euid = geteuid();
2322 if (uid_wrapper_enabled()) {
2323 unsetenv("UID_WRAPPER_MYUID");
2326 dce_ctx->endpoint_list = NULL;
2327 dce_ctx->lp_ctx = lp_ctx;
2328 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2329 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2330 dce_ctx->broken_connections = NULL;
2332 for (i=0;endpoint_servers[i];i++) {
2333 const struct dcesrv_endpoint_server *ep_server;
2335 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2337 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2338 return NT_STATUS_INTERNAL_ERROR;
2341 status = ep_server->init_server(dce_ctx, ep_server);
2342 if (!NT_STATUS_IS_OK(status)) {
2343 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2344 nt_errstr(status)));
2349 *_dce_ctx = dce_ctx;
2350 return NT_STATUS_OK;
2353 /* the list of currently registered DCERPC endpoint servers.
2355 static struct ep_server {
2356 struct dcesrv_endpoint_server *ep_server;
2357 } *ep_servers = NULL;
2358 static int num_ep_servers;
2361 register a DCERPC endpoint server.
2363 The 'name' can be later used by other backends to find the operations
2364 structure for this backend.
2367 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2370 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2371 /* its already registered! */
2372 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2374 return NT_STATUS_OBJECT_NAME_COLLISION;
2377 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2379 smb_panic("out of memory in dcerpc_register");
2382 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2383 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2387 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2390 return NT_STATUS_OK;
2394 return the operations structure for a named backend of the specified type
2396 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2400 for (i=0;i<num_ep_servers;i++) {
2401 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2402 return ep_servers[i].ep_server;
2409 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2411 static bool initialized;
2412 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2413 STATIC_dcerpc_server_MODULES_PROTO;
2414 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2415 init_module_fn *shared_init;
2422 shared_init = load_samba_modules(NULL, "dcerpc_server");
2424 run_init_functions(NULL, static_init);
2425 run_init_functions(NULL, shared_init);
2427 talloc_free(shared_init);
2431 return the DCERPC module version, and the size of some critical types
2432 This can be used by endpoint server modules to either detect compilation errors, or provide
2433 multiple implementations for different smbd compilation options in one module
2435 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2437 static const struct dcesrv_critical_sizes critical_sizes = {
2438 DCERPC_MODULE_VERSION,
2439 sizeof(struct dcesrv_context),
2440 sizeof(struct dcesrv_endpoint),
2441 sizeof(struct dcesrv_endpoint_server),
2442 sizeof(struct dcesrv_interface),
2443 sizeof(struct dcesrv_if_list),
2444 sizeof(struct dcesrv_connection),
2445 sizeof(struct dcesrv_call_state),
2446 sizeof(struct dcesrv_auth),
2447 sizeof(struct dcesrv_handle)
2450 return &critical_sizes;
2453 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2455 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2456 struct stream_connection *srv_conn;
2457 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2458 struct stream_connection);
2460 dce_conn->wait_send = NULL;
2461 dce_conn->wait_recv = NULL;
2462 dce_conn->wait_private = NULL;
2464 dce_conn->allow_bind = false;
2465 dce_conn->allow_alter = false;
2467 dce_conn->default_auth_state->auth_invalid = true;
2469 if (dce_conn->pending_call_list == NULL) {
2470 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2472 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2473 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2477 if (dce_conn->terminate != NULL) {
2481 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2483 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2484 if (dce_conn->terminate == NULL) {
2485 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2487 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2490 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2492 struct dcesrv_connection *cur, *next;
2494 next = dce_ctx->broken_connections;
2495 while (next != NULL) {
2499 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2500 struct dcesrv_connection_context *context_cur, *context_next;
2502 context_next = cur->contexts;
2503 while (context_next != NULL) {
2504 context_cur = context_next;
2505 context_next = context_cur->next;
2507 dcesrv_connection_context_destructor(context_cur);
2511 dcesrv_terminate_connection(cur, cur->terminate);
2515 /* We need this include to be able to compile on some plateforms
2516 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2518 * It has to be that deep because otherwise we have a conflict on
2519 * const struct dcesrv_interface declaration.
2520 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2521 * which conflict with the bind used before.
2523 #include "system/network.h"
2525 struct dcesrv_sock_reply_state {
2526 struct dcesrv_connection *dce_conn;
2527 struct dcesrv_call_state *call;
2531 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2532 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2534 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2536 struct dcesrv_call_state *call;
2538 call = dce_conn->call_list;
2539 if (!call || !call->replies) {
2543 while (call->replies) {
2544 struct data_blob_list_item *rep = call->replies;
2545 struct dcesrv_sock_reply_state *substate;
2546 struct tevent_req *subreq;
2548 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2550 dcesrv_terminate_connection(dce_conn, "no memory");
2554 substate->dce_conn = dce_conn;
2555 substate->call = NULL;
2557 DLIST_REMOVE(call->replies, rep);
2559 if (call->replies == NULL && call->terminate_reason == NULL) {
2560 substate->call = call;
2563 substate->iov.iov_base = (void *) rep->blob.data;
2564 substate->iov.iov_len = rep->blob.length;
2566 subreq = tstream_writev_queue_send(substate,
2567 dce_conn->event_ctx,
2569 dce_conn->send_queue,
2572 dcesrv_terminate_connection(dce_conn, "no memory");
2575 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2579 if (call->terminate_reason != NULL) {
2580 struct tevent_req *subreq;
2582 subreq = tevent_queue_wait_send(call,
2583 dce_conn->event_ctx,
2584 dce_conn->send_queue);
2586 dcesrv_terminate_connection(dce_conn, __location__);
2589 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2593 DLIST_REMOVE(call->conn->call_list, call);
2594 call->list = DCESRV_LIST_NONE;
2597 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2599 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2600 struct dcesrv_sock_reply_state);
2604 struct dcesrv_call_state *call = substate->call;
2606 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2607 TALLOC_FREE(subreq);
2609 status = map_nt_error_from_unix_common(sys_errno);
2610 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2614 talloc_free(substate);
2620 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2622 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2624 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2625 struct dcesrv_call_state);
2629 /* make sure we stop send queue before removing subreq */
2630 tevent_queue_stop(call->conn->send_queue);
2632 ok = tevent_queue_wait_recv(subreq);
2633 TALLOC_FREE(subreq);
2635 dcesrv_terminate_connection(call->conn, __location__);
2639 /* disconnect after 200 usecs */
2640 tv = timeval_current_ofs_usec(200);
2641 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2642 if (subreq == NULL) {
2643 dcesrv_terminate_connection(call->conn, __location__);
2646 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2650 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2652 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2653 struct dcesrv_call_state);
2656 ok = tevent_wakeup_recv(subreq);
2657 TALLOC_FREE(subreq);
2659 dcesrv_terminate_connection(call->conn, __location__);
2663 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2666 struct dcesrv_socket_context {
2667 const struct dcesrv_endpoint *endpoint;
2668 struct dcesrv_context *dcesrv_ctx;
2672 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2674 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2677 struct dcesrv_socket_context *dcesrv_sock =
2678 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2679 enum dcerpc_transport_t transport =
2680 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2681 struct dcesrv_connection *dcesrv_conn = NULL;
2683 struct tevent_req *subreq;
2684 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2686 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2688 if (!srv_conn->session_info) {
2689 status = auth_anonymous_session_info(srv_conn,
2691 &srv_conn->session_info);
2692 if (!NT_STATUS_IS_OK(status)) {
2693 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2694 nt_errstr(status)));
2695 stream_terminate_connection(srv_conn, nt_errstr(status));
2701 * This fills in dcesrv_conn->endpoint with the endpoint
2702 * associated with the socket. From this point on we know
2703 * which (group of) services we are handling, but not the
2704 * specific interface.
2707 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2709 dcesrv_sock->endpoint,
2710 srv_conn->session_info,
2711 srv_conn->event.ctx,
2713 srv_conn->server_id,
2714 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2716 if (!NT_STATUS_IS_OK(status)) {
2717 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2718 nt_errstr(status)));
2719 stream_terminate_connection(srv_conn, nt_errstr(status));
2723 dcesrv_conn->transport.private_data = srv_conn;
2724 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2726 TALLOC_FREE(srv_conn->event.fde);
2728 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2729 if (!dcesrv_conn->send_queue) {
2730 status = NT_STATUS_NO_MEMORY;
2731 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2732 nt_errstr(status)));
2733 stream_terminate_connection(srv_conn, nt_errstr(status));
2737 if (transport == NCACN_NP) {
2738 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2739 &srv_conn->tstream);
2741 ret = tstream_bsd_existing_socket(dcesrv_conn,
2742 socket_get_fd(srv_conn->socket),
2743 &dcesrv_conn->stream);
2745 status = map_nt_error_from_unix_common(errno);
2746 DEBUG(0, ("dcesrv_sock_accept: "
2747 "failed to setup tstream: %s\n",
2748 nt_errstr(status)));
2749 stream_terminate_connection(srv_conn, nt_errstr(status));
2752 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2755 dcesrv_conn->local_address = srv_conn->local_address;
2756 dcesrv_conn->remote_address = srv_conn->remote_address;
2758 if (transport == NCALRPC) {
2763 sock_fd = socket_get_fd(srv_conn->socket);
2764 if (sock_fd == -1) {
2765 stream_terminate_connection(
2766 srv_conn, "socket_get_fd failed\n");
2770 ret = getpeereid(sock_fd, &uid, &gid);
2772 status = map_nt_error_from_unix_common(errno);
2773 DEBUG(0, ("dcesrv_sock_accept: "
2774 "getpeereid() failed for NCALRPC: %s\n",
2775 nt_errstr(status)));
2776 stream_terminate_connection(srv_conn, nt_errstr(status));
2779 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2780 struct tsocket_address *r = NULL;
2782 ret = tsocket_address_unix_from_path(dcesrv_conn,
2783 AS_SYSTEM_MAGIC_PATH_TOKEN,
2786 status = map_nt_error_from_unix_common(errno);
2787 DEBUG(0, ("dcesrv_sock_accept: "
2788 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2789 nt_errstr(status)));
2790 stream_terminate_connection(srv_conn, nt_errstr(status));
2793 dcesrv_conn->remote_address = r;
2797 srv_conn->private_data = dcesrv_conn;
2799 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2800 dcesrv_conn->event_ctx,
2801 dcesrv_conn->stream);
2803 status = NT_STATUS_NO_MEMORY;
2804 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2805 nt_errstr(status)));
2806 stream_terminate_connection(srv_conn, nt_errstr(status));
2809 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2814 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2816 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2818 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2819 struct dcesrv_connection);
2820 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2821 struct ncacn_packet *pkt;
2825 if (dce_conn->terminate) {
2827 * if the current connection is broken
2828 * we need to clean it up before any other connection
2830 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2831 dcesrv_cleanup_broken_connections(dce_ctx);
2835 dcesrv_cleanup_broken_connections(dce_ctx);
2837 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2839 TALLOC_FREE(subreq);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2845 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2846 if (!NT_STATUS_IS_OK(status)) {
2847 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2852 * This is used to block the connection during
2853 * pending authentication.
2855 if (dce_conn->wait_send != NULL) {
2856 subreq = dce_conn->wait_send(dce_conn,
2857 dce_conn->event_ctx,
2858 dce_conn->wait_private);
2860 status = NT_STATUS_NO_MEMORY;
2861 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2864 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2868 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2869 dce_conn->event_ctx,
2872 status = NT_STATUS_NO_MEMORY;
2873 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2876 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2879 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2881 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2882 struct dcesrv_connection);
2883 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2886 if (dce_conn->terminate) {
2888 * if the current connection is broken
2889 * we need to clean it up before any other connection
2891 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2892 dcesrv_cleanup_broken_connections(dce_ctx);
2896 dcesrv_cleanup_broken_connections(dce_ctx);
2898 status = dce_conn->wait_recv(subreq);
2899 dce_conn->wait_send = NULL;
2900 dce_conn->wait_recv = NULL;
2901 dce_conn->wait_private = NULL;
2902 TALLOC_FREE(subreq);
2903 if (!NT_STATUS_IS_OK(status)) {
2904 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2908 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2909 dce_conn->event_ctx,
2912 status = NT_STATUS_NO_MEMORY;
2913 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2916 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2919 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2921 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2922 struct dcesrv_connection);
2923 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2926 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2928 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2929 struct dcesrv_connection);
2930 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2934 static const struct stream_server_ops dcesrv_stream_ops = {
2936 .accept_connection = dcesrv_sock_accept,
2937 .recv_handler = dcesrv_sock_recv,
2938 .send_handler = dcesrv_sock_send,
2941 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2942 struct loadparm_context *lp_ctx,
2943 struct dcesrv_endpoint *e,
2944 struct tevent_context *event_ctx,
2945 const struct model_ops *model_ops,
2946 void *process_context)
2948 struct dcesrv_socket_context *dcesrv_sock;
2951 const char *endpoint;
2953 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2954 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2956 /* remember the endpoint of this socket */
2957 dcesrv_sock->endpoint = e;
2958 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2960 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2962 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2963 model_ops, &dcesrv_stream_ops,
2964 "unix", endpoint, &port,
2965 lpcfg_socket_options(lp_ctx),
2966 dcesrv_sock, process_context);
2967 if (!NT_STATUS_IS_OK(status)) {
2968 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2969 endpoint, nt_errstr(status)));
2975 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2976 struct loadparm_context *lp_ctx,
2977 struct dcesrv_endpoint *e,
2978 struct tevent_context *event_ctx,
2979 const struct model_ops *model_ops,
2980 void *process_context)
2982 struct dcesrv_socket_context *dcesrv_sock;
2986 const char *endpoint;
2988 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2990 if (endpoint == NULL) {
2992 * No identifier specified: use DEFAULT.
2994 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2995 * no endpoint and let the epmapper worry about it.
2997 endpoint = "DEFAULT";
2998 status = dcerpc_binding_set_string_option(e->ep_description,
3001 if (!NT_STATUS_IS_OK(status)) {
3002 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
3003 nt_errstr(status)));
3008 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
3011 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3012 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3014 /* remember the endpoint of this socket */
3015 dcesrv_sock->endpoint = e;
3016 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3018 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3019 model_ops, &dcesrv_stream_ops,
3020 "unix", full_path, &port,
3021 lpcfg_socket_options(lp_ctx),
3022 dcesrv_sock, process_context);
3023 if (!NT_STATUS_IS_OK(status)) {
3024 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3025 endpoint, full_path, nt_errstr(status)));
3030 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3031 struct loadparm_context *lp_ctx,
3032 struct dcesrv_endpoint *e,
3033 struct tevent_context *event_ctx,
3034 const struct model_ops *model_ops,
3035 void *process_context)
3037 struct dcesrv_socket_context *dcesrv_sock;
3039 const char *endpoint;
3041 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3042 if (endpoint == NULL) {
3043 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3044 return NT_STATUS_INVALID_PARAMETER;
3047 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3048 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3050 /* remember the endpoint of this socket */
3051 dcesrv_sock->endpoint = e;
3052 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3054 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3055 model_ops, &dcesrv_stream_ops,
3057 dcesrv_sock, process_context);
3058 if (!NT_STATUS_IS_OK(status)) {
3059 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3060 endpoint, nt_errstr(status)));
3064 return NT_STATUS_OK;
3068 add a socket address to the list of events, one event per dcerpc endpoint
3070 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3071 struct dcesrv_endpoint *e,
3072 struct tevent_context *event_ctx,
3073 const struct model_ops *model_ops,
3074 const char *address,
3075 void *process_context)
3077 struct dcesrv_socket_context *dcesrv_sock;
3080 const char *endpoint;
3083 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3084 if (endpoint != NULL) {
3085 port = atoi(endpoint);
3088 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3089 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3091 /* remember the endpoint of this socket */
3092 dcesrv_sock->endpoint = e;
3093 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3095 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3096 model_ops, &dcesrv_stream_ops,
3097 "ip", address, &port,
3098 lpcfg_socket_options(dce_ctx->lp_ctx),
3099 dcesrv_sock, process_context);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 struct dcesrv_if_list *iface;
3102 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3104 for (iface = e->interface_list; iface; iface = iface->next) {
3105 DEBUGADD(0, ("%s ", iface->iface.name));
3107 DEBUGADD(0, ("failed - %s",
3108 nt_errstr(status)));
3112 snprintf(port_str, sizeof(port_str), "%u", port);
3114 status = dcerpc_binding_set_string_option(e->ep_description,
3115 "endpoint", port_str);
3116 if (!NT_STATUS_IS_OK(status)) {
3117 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3118 port_str, nt_errstr(status)));
3121 struct dcesrv_if_list *iface;
3122 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3123 address, port_str));
3124 for (iface = e->interface_list; iface; iface = iface->next) {
3125 DEBUGADD(4, ("%s ", iface->iface.name));
3127 DEBUGADD(4, ("\n"));
3130 return NT_STATUS_OK;
3133 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3135 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3136 struct loadparm_context *lp_ctx,
3137 struct dcesrv_endpoint *e,
3138 struct tevent_context *event_ctx,
3139 const struct model_ops *model_ops,
3140 void *process_context)
3144 /* Add TCP/IP sockets */
3145 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3148 struct interface *ifaces;
3150 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3152 num_interfaces = iface_list_count(ifaces);
3153 for(i = 0; i < num_interfaces; i++) {
3154 const char *address = iface_list_n_ip(ifaces, i);
3155 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3158 NT_STATUS_NOT_OK_RETURN(status);
3163 size_t num_binds = 0;
3164 wcard = iface_list_wildcard(dce_ctx);
3165 NT_STATUS_HAVE_NO_MEMORY(wcard);
3166 for (i=0; wcard[i]; i++) {
3167 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3168 model_ops, wcard[i],
3170 if (NT_STATUS_IS_OK(status)) {
3175 if (num_binds == 0) {
3176 return NT_STATUS_INVALID_PARAMETER_MIX;
3180 return NT_STATUS_OK;
3183 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3184 struct loadparm_context *lp_ctx,
3185 struct dcesrv_endpoint *e,
3186 struct tevent_context *event_ctx,
3187 const struct model_ops *model_ops,
3188 void *process_context)
3190 enum dcerpc_transport_t transport =
3191 dcerpc_binding_get_transport(e->ep_description);
3193 switch (transport) {
3194 case NCACN_UNIX_STREAM:
3195 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3196 model_ops, process_context);
3199 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3200 model_ops, process_context);
3203 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3204 model_ops, process_context);
3207 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3208 model_ops, process_context);
3211 return NT_STATUS_NOT_SUPPORTED;
3217 * retrieve credentials from a dce_call
3219 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3221 struct dcesrv_auth *auth = dce_call->auth_state;
3222 SMB_ASSERT(auth->auth_finished);
3223 return auth->session_info->credentials;
3227 * returns true if this is an authenticated call
3229 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3231 struct dcesrv_auth *auth = dce_call->auth_state;
3232 enum security_user_level level;
3233 SMB_ASSERT(auth->auth_finished);
3234 level = security_session_user_level(auth->session_info, NULL);
3235 return level >= SECURITY_USER;
3239 * retrieve account_name for a dce_call
3241 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3243 struct dcesrv_auth *auth = dce_call->auth_state;
3244 SMB_ASSERT(auth->auth_finished);
3245 return auth->session_info->info->account_name;
3249 * retrieve session_info from a dce_call
3251 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3253 struct dcesrv_auth *auth = dce_call->auth_state;
3254 SMB_ASSERT(auth->auth_finished);
3255 return auth->session_info;
3259 * retrieve auth type/level from a dce_call
3261 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3262 enum dcerpc_AuthType *auth_type,
3263 enum dcerpc_AuthLevel *auth_level)
3265 struct dcesrv_auth *auth = dce_call->auth_state;
3267 SMB_ASSERT(auth->auth_finished);
3269 if (auth_type != NULL) {
3270 *auth_type = auth->auth_type;
3272 if (auth_level != NULL) {
3273 *auth_level = auth->auth_level;