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 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
463 DATA_BLOB *session_key)
465 if (p->auth_state.session_info->session_key.length) {
466 *session_key = p->auth_state.session_info->session_key;
469 return NT_STATUS_NO_USER_SESSION_KEY;
473 * Fetch the authentication session key if available.
475 * This is the key generated by a gensec authentication.
478 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
479 DATA_BLOB *session_key)
481 return dcesrv_inherited_session_key(call->conn, session_key);
485 fetch the user session key - may be default (above) or the SMB session key
487 The key is always truncated to 16 bytes
489 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
490 DATA_BLOB *session_key)
492 NTSTATUS status = p->auth_state.session_key(p, session_key);
493 if (!NT_STATUS_IS_OK(status)) {
497 session_key->length = MIN(session_key->length, 16);
503 * Fetch the transport session key if available.
504 * Typically this is the SMB session key
505 * or a fixed key for local transports.
507 * The key is always truncated to 16 bytes.
509 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
510 DATA_BLOB *session_key)
512 return dcesrv_fetch_session_key(call->conn, session_key);
516 connect to a dcerpc endpoint
518 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
520 const struct dcesrv_endpoint *ep,
521 struct auth_session_info *session_info,
522 struct tevent_context *event_ctx,
523 struct imessaging_context *msg_ctx,
524 struct server_id server_id,
525 uint32_t state_flags,
526 struct dcesrv_connection **_p)
528 struct dcesrv_connection *p;
531 return NT_STATUS_ACCESS_DENIED;
534 p = talloc_zero(mem_ctx, struct dcesrv_connection);
535 NT_STATUS_HAVE_NO_MEMORY(p);
537 if (!talloc_reference(p, session_info)) {
539 return NT_STATUS_NO_MEMORY;
542 p->dce_ctx = dce_ctx;
544 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
545 p->auth_state.session_info = session_info;
546 p->auth_state.session_key = dcesrv_generic_session_key;
547 p->event_ctx = event_ctx;
548 p->msg_ctx = msg_ctx;
549 p->server_id = server_id;
550 p->state_flags = state_flags;
551 p->allow_bind = true;
552 p->max_recv_frag = 5840;
553 p->max_xmit_frag = 5840;
554 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
557 * For now we only support NDR32.
559 p->preferred_transfer = &ndr_transfer_syntax_ndr;
566 move a call from an existing linked list to the specified list. This
567 prevents bugs where we forget to remove the call from a previous
570 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
571 enum dcesrv_call_list list)
573 switch (call->list) {
574 case DCESRV_LIST_NONE:
576 case DCESRV_LIST_CALL_LIST:
577 DLIST_REMOVE(call->conn->call_list, call);
579 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
580 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
582 case DCESRV_LIST_PENDING_CALL_LIST:
583 DLIST_REMOVE(call->conn->pending_call_list, call);
588 case DCESRV_LIST_NONE:
590 case DCESRV_LIST_CALL_LIST:
591 DLIST_ADD_END(call->conn->call_list, call);
593 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
594 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
596 case DCESRV_LIST_PENDING_CALL_LIST:
597 DLIST_ADD_END(call->conn->pending_call_list, call);
602 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
605 if (call->conn->terminate != NULL) {
609 call->conn->allow_bind = false;
610 call->conn->allow_alter = false;
611 call->conn->allow_auth3 = false;
612 call->conn->allow_request = false;
614 call->terminate_reason = talloc_strdup(call, reason);
615 if (call->terminate_reason == NULL) {
616 call->terminate_reason = __location__;
621 return a dcerpc bind_nak
623 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
625 struct ncacn_packet pkt;
626 struct dcerpc_bind_nak_version version;
627 struct data_blob_list_item *rep;
629 static const uint8_t _pad[3] = { 0, };
632 * We add the call to the pending_call_list
633 * in order to defer the termination.
635 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
637 /* setup a bind_nak */
638 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
640 pkt.call_id = call->pkt.call_id;
641 pkt.ptype = DCERPC_PKT_BIND_NAK;
642 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
643 pkt.u.bind_nak.reject_reason = reason;
644 version.rpc_vers = 5;
645 version.rpc_vers_minor = 0;
646 pkt.u.bind_nak.num_versions = 1;
647 pkt.u.bind_nak.versions = &version;
648 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
650 rep = talloc_zero(call, struct data_blob_list_item);
652 return NT_STATUS_NO_MEMORY;
655 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
656 if (!NT_STATUS_IS_OK(status)) {
660 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
662 DLIST_ADD_END(call->replies, rep);
663 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
665 if (call->conn->call_list && call->conn->call_list->replies) {
666 if (call->conn->transport.report_output_data) {
667 call->conn->transport.report_output_data(call->conn);
674 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
678 * We add the call to the pending_call_list
679 * in order to defer the termination.
681 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
683 return dcesrv_fault_with_flags(call, fault_code,
684 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
687 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
689 DLIST_REMOVE(c->conn->contexts, c);
691 if (c->iface && c->iface->unbind) {
692 c->iface->unbind(c, c->iface);
699 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
701 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
702 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
703 enum dcerpc_transport_t transport =
704 dcerpc_binding_get_transport(endpoint->ep_description);
705 struct dcesrv_connection_context *context = dce_call->context;
706 const struct dcesrv_interface *iface = context->iface;
708 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
710 if (transport == NCALRPC) {
711 context->allow_connect = true;
716 * allow overwrite per interface
717 * allow dcerpc auth level connect:<interface>
719 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
720 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
721 "allow dcerpc auth level connect",
723 context->allow_connect);
726 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
727 const struct dcesrv_interface *iface)
729 if (dce_call->context == NULL) {
730 return NT_STATUS_INTERNAL_ERROR;
734 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
735 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
737 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
741 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
742 const struct dcesrv_interface *iface)
744 if (dce_call->context == NULL) {
745 return NT_STATUS_INTERNAL_ERROR;
748 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
752 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
753 const struct dcesrv_interface *iface)
755 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
756 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
757 enum dcerpc_transport_t transport =
758 dcerpc_binding_get_transport(endpoint->ep_description);
759 struct dcesrv_connection_context *context = dce_call->context;
761 if (context == NULL) {
762 return NT_STATUS_INTERNAL_ERROR;
765 if (transport == NCALRPC) {
766 context->allow_connect = true;
771 * allow overwrite per interface
772 * allow dcerpc auth level connect:<interface>
774 context->allow_connect = false;
775 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
776 "allow dcerpc auth level connect",
778 context->allow_connect);
782 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
783 const struct dcesrv_interface *iface)
785 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
786 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
787 enum dcerpc_transport_t transport =
788 dcerpc_binding_get_transport(endpoint->ep_description);
789 struct dcesrv_connection_context *context = dce_call->context;
791 if (context == NULL) {
792 return NT_STATUS_INTERNAL_ERROR;
795 if (transport == NCALRPC) {
796 context->allow_connect = true;
801 * allow overwrite per interface
802 * allow dcerpc auth level connect:<interface>
804 context->allow_connect = true;
805 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
806 "allow dcerpc auth level connect",
808 context->allow_connect);
812 struct dcesrv_conn_auth_wait_context {
813 struct tevent_req *req;
818 struct dcesrv_conn_auth_wait_state {
822 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
823 struct tevent_context *ev,
826 struct dcesrv_conn_auth_wait_context *auth_wait =
827 talloc_get_type_abort(private_data,
828 struct dcesrv_conn_auth_wait_context);
829 struct tevent_req *req = NULL;
830 struct dcesrv_conn_auth_wait_state *state = NULL;
832 req = tevent_req_create(mem_ctx, &state,
833 struct dcesrv_conn_auth_wait_state);
837 auth_wait->req = req;
839 tevent_req_defer_callback(req, ev);
841 if (!auth_wait->done) {
845 if (tevent_req_nterror(req, auth_wait->status)) {
846 return tevent_req_post(req, ev);
849 tevent_req_done(req);
850 return tevent_req_post(req, ev);
853 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
855 return tevent_req_simple_recv_ntstatus(req);
858 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
860 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
862 if (conn->wait_send != NULL) {
863 return NT_STATUS_INTERNAL_ERROR;
866 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
867 if (auth_wait == NULL) {
868 return NT_STATUS_NO_MEMORY;
871 conn->wait_private = auth_wait;
872 conn->wait_send = dcesrv_conn_auth_wait_send;
873 conn->wait_recv = dcesrv_conn_auth_wait_recv;
877 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
880 struct dcesrv_conn_auth_wait_context *auth_wait =
881 talloc_get_type_abort(conn->wait_private,
882 struct dcesrv_conn_auth_wait_context);
884 auth_wait->done = true;
885 auth_wait->status = status;
887 if (auth_wait->req == NULL) {
891 if (tevent_req_nterror(auth_wait->req, status)) {
895 tevent_req_done(auth_wait->req);
898 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
900 static void dcesrv_bind_done(struct tevent_req *subreq);
903 handle a bind request
905 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
907 struct dcesrv_connection *conn = call->conn;
908 struct ncacn_packet *pkt = &call->ack_pkt;
910 uint32_t extra_flags = 0;
911 uint16_t max_req = 0;
912 uint16_t max_rep = 0;
913 const char *ep_prefix = "";
914 const char *endpoint = NULL;
915 struct dcesrv_auth *auth = &call->conn->auth_state;
916 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
917 struct dcerpc_ack_ctx *ack_features = NULL;
918 struct tevent_req *subreq = NULL;
921 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
923 call->pkt.u.bind.auth_info.length,
924 0, /* required flags */
925 DCERPC_PFC_FLAG_FIRST |
926 DCERPC_PFC_FLAG_LAST |
927 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
928 0x08 | /* this is not defined, but should be ignored */
929 DCERPC_PFC_FLAG_CONC_MPX |
930 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
931 DCERPC_PFC_FLAG_MAYBE |
932 DCERPC_PFC_FLAG_OBJECT_UUID);
933 if (!NT_STATUS_IS_OK(status)) {
934 return dcesrv_bind_nak(call,
935 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
938 /* max_recv_frag and max_xmit_frag result always in the same value! */
939 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
940 call->pkt.u.bind.max_recv_frag);
942 * The values are between 2048 and 5840 tested against Windows 2012R2
943 * via ncacn_ip_tcp on port 135.
945 max_req = MAX(2048, max_req);
946 max_rep = MIN(max_req, call->conn->max_recv_frag);
947 /* They are truncated to an 8 byte boundary. */
950 /* max_recv_frag and max_xmit_frag result always in the same value! */
951 call->conn->max_recv_frag = max_rep;
952 call->conn->max_xmit_frag = max_rep;
955 if provided, check the assoc_group is valid
957 if (call->pkt.u.bind.assoc_group_id != 0) {
958 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
960 call->pkt.u.bind.assoc_group_id);
962 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
963 call->conn->dce_ctx);
967 * The NETLOGON server does not use handles and so
968 * there is no need to support association groups, but
969 * we need to give back a number regardless.
971 * We have to do this when it is not run as a single process,
972 * because then it can't see the other valid association
973 * groups. We handle this genericly for all endpoints not
974 * running in single process mode.
976 * We know which endpoint we are on even before checking the
977 * iface UUID, so for simplicity we enforce the same policy
978 * for all interfaces on the endpoint.
980 * This means that where NETLOGON
981 * shares an endpoint (such as ncalrpc or of 'lsa over
982 * netlogon' is set) we will still check association groups.
986 if (call->conn->assoc_group == NULL &&
987 !call->conn->endpoint->use_single_process) {
988 call->conn->assoc_group
989 = dcesrv_assoc_group_new(call->conn,
990 call->conn->dce_ctx);
992 if (call->conn->assoc_group == NULL) {
993 return dcesrv_bind_nak(call, 0);
996 if (call->pkt.u.bind.num_contexts < 1) {
997 return dcesrv_bind_nak(call, 0);
1000 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1001 call->pkt.u.bind.num_contexts);
1002 if (ack_ctx_list == NULL) {
1003 return dcesrv_bind_nak(call, 0);
1007 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1008 * dcesrv_check_or_create_context()) and do some protocol validation
1009 * and set sane defaults.
1011 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1012 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1013 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1014 bool is_feature = false;
1015 uint64_t features = 0;
1017 if (c->num_transfer_syntaxes == 0) {
1018 return dcesrv_bind_nak(call, 0);
1021 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1022 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1025 * It's only treated as bind time feature request, if the first
1026 * transfer_syntax matches, all others are ignored.
1028 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1034 if (ack_features != NULL) {
1036 * Only one bind time feature context is allowed.
1038 return dcesrv_bind_nak(call, 0);
1042 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1043 a->reason.negotiate = 0;
1044 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1045 /* not supported yet */
1047 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1048 a->reason.negotiate |=
1049 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1052 call->conn->bind_time_features = a->reason.negotiate;
1056 * Try to negotiate one new presentation context.
1058 * Deep in here we locate the iface (by uuid) that the client
1059 * requested, from the list of interfaces on the
1060 * call->conn->endpoint, and call iface->bind() on that iface.
1062 * call->conn was set up at the accept() of the socket, and
1063 * call->conn->endpoint has a list of interfaces restricted to
1064 * this port or pipe.
1066 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1067 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1068 return dcesrv_bind_nak(call, 0);
1070 if (!NT_STATUS_IS_OK(status)) {
1075 * At this point we still don't know which interface (eg
1076 * netlogon, lsa, drsuapi) the caller requested in this bind!
1077 * The most recently added context is available as the first
1078 * element in the linked list at call->conn->contexts, that is
1079 * call->conn->contexts->iface, but they may not have
1080 * requested one at all!
1083 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1084 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1085 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1086 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1089 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1090 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1094 * After finding the interface and setting up the NDR
1095 * transport negotiation etc, handle any authentication that
1096 * is being requested.
1098 if (!dcesrv_auth_bind(call)) {
1100 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1102 * With DCERPC_AUTH_LEVEL_NONE, we get the
1103 * reject_reason in auth->auth_context_id.
1105 return dcesrv_bind_nak(call, auth->auth_context_id);
1109 * This must a be a temporary failure e.g. talloc or invalid
1110 * configuration, e.g. no machine account.
1112 return dcesrv_bind_nak(call,
1113 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1116 /* setup a bind_ack */
1117 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1118 pkt->auth_length = 0;
1119 pkt->call_id = call->pkt.call_id;
1120 pkt->ptype = DCERPC_PKT_BIND_ACK;
1121 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1122 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1123 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1124 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1126 endpoint = dcerpc_binding_get_string_option(
1127 call->conn->endpoint->ep_description,
1129 if (endpoint == NULL) {
1133 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1135 * TODO: check if this is really needed
1137 * Or if we should fix this in our idl files.
1139 ep_prefix = "\\PIPE\\";
1143 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1146 if (pkt->u.bind_ack.secondary_address == NULL) {
1147 return NT_STATUS_NO_MEMORY;
1149 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1150 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1151 pkt->u.bind_ack.auth_info = data_blob_null;
1153 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 return dcesrv_bind_nak(call, 0);
1158 if (auth->auth_finished) {
1159 return dcesrv_auth_reply(call);
1162 subreq = gensec_update_send(call, call->event_ctx,
1163 auth->gensec_security,
1164 call->in_auth_info.credentials);
1165 if (subreq == NULL) {
1166 return NT_STATUS_NO_MEMORY;
1168 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1170 return dcesrv_conn_auth_wait_setup(conn);
1173 static void dcesrv_bind_done(struct tevent_req *subreq)
1175 struct dcesrv_call_state *call =
1176 tevent_req_callback_data(subreq,
1177 struct dcesrv_call_state);
1178 struct dcesrv_connection *conn = call->conn;
1181 status = gensec_update_recv(subreq, call,
1182 &call->out_auth_info->credentials);
1183 TALLOC_FREE(subreq);
1185 status = dcesrv_auth_complete(call, status);
1186 if (!NT_STATUS_IS_OK(status)) {
1187 status = dcesrv_bind_nak(call, 0);
1188 dcesrv_conn_auth_wait_finished(conn, status);
1192 status = dcesrv_auth_reply(call);
1193 dcesrv_conn_auth_wait_finished(conn, status);
1197 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1199 struct ncacn_packet *pkt = &call->ack_pkt;
1200 struct data_blob_list_item *rep = NULL;
1203 rep = talloc_zero(call, struct data_blob_list_item);
1205 return NT_STATUS_NO_MEMORY;
1208 status = ncacn_push_auth(&rep->blob, call, pkt,
1209 call->out_auth_info);
1210 if (!NT_STATUS_IS_OK(status)) {
1214 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1216 DLIST_ADD_END(call->replies, rep);
1217 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1219 if (call->conn->call_list && call->conn->call_list->replies) {
1220 if (call->conn->transport.report_output_data) {
1221 call->conn->transport.report_output_data(call->conn);
1225 return NT_STATUS_OK;
1229 static void dcesrv_auth3_done(struct tevent_req *subreq);
1232 handle a auth3 request
1234 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1236 struct dcesrv_connection *conn = call->conn;
1237 struct dcesrv_auth *auth = &call->conn->auth_state;
1238 struct tevent_req *subreq = NULL;
1241 if (!call->conn->allow_auth3) {
1242 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1245 if (call->conn->auth_state.auth_finished) {
1246 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1249 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1251 call->pkt.u.auth3.auth_info.length,
1252 0, /* required flags */
1253 DCERPC_PFC_FLAG_FIRST |
1254 DCERPC_PFC_FLAG_LAST |
1255 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1256 0x08 | /* this is not defined, but should be ignored */
1257 DCERPC_PFC_FLAG_CONC_MPX |
1258 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1259 DCERPC_PFC_FLAG_MAYBE |
1260 DCERPC_PFC_FLAG_OBJECT_UUID);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1265 /* handle the auth3 in the auth code */
1266 if (!dcesrv_auth_prepare_auth3(call)) {
1268 * we don't send a reply to a auth3 request,
1269 * except by a fault.
1271 * In anycase we mark the connection as
1274 call->conn->auth_state.auth_invalid = true;
1275 if (call->fault_code != 0) {
1276 return dcesrv_fault_disconnect(call, call->fault_code);
1279 return NT_STATUS_OK;
1282 subreq = gensec_update_send(call, call->event_ctx,
1283 auth->gensec_security,
1284 call->in_auth_info.credentials);
1285 if (subreq == NULL) {
1286 return NT_STATUS_NO_MEMORY;
1288 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1290 return dcesrv_conn_auth_wait_setup(conn);
1293 static void dcesrv_auth3_done(struct tevent_req *subreq)
1295 struct dcesrv_call_state *call =
1296 tevent_req_callback_data(subreq,
1297 struct dcesrv_call_state);
1298 struct dcesrv_connection *conn = call->conn;
1301 status = gensec_update_recv(subreq, call,
1302 &call->out_auth_info->credentials);
1303 TALLOC_FREE(subreq);
1305 status = dcesrv_auth_complete(call, status);
1306 if (!NT_STATUS_IS_OK(status)) {
1308 * we don't send a reply to a auth3 request,
1309 * except by a fault.
1311 * In anycase we mark the connection as
1314 call->conn->auth_state.auth_invalid = true;
1315 if (call->fault_code != 0) {
1316 status = dcesrv_fault_disconnect(call, call->fault_code);
1317 dcesrv_conn_auth_wait_finished(conn, status);
1321 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1326 * we don't send a reply to a auth3 request.
1329 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1334 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1335 const struct dcerpc_bind *b,
1336 const struct dcerpc_ctx_list *ctx,
1337 struct dcerpc_ack_ctx *ack,
1339 const struct ndr_syntax_id *supported_transfer)
1341 uint32_t if_version;
1342 struct dcesrv_connection_context *context;
1343 const struct dcesrv_interface *iface;
1346 const struct ndr_syntax_id *selected_transfer = NULL;
1351 return NT_STATUS_INTERNAL_ERROR;
1354 return NT_STATUS_INTERNAL_ERROR;
1356 if (ctx->num_transfer_syntaxes < 1) {
1357 return NT_STATUS_INTERNAL_ERROR;
1360 return NT_STATUS_INTERNAL_ERROR;
1362 if (supported_transfer == NULL) {
1363 return NT_STATUS_INTERNAL_ERROR;
1366 switch (ack->result) {
1367 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1368 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1370 * We is already completed.
1372 return NT_STATUS_OK;
1377 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1378 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1380 if_version = ctx->abstract_syntax.if_version;
1381 uuid = ctx->abstract_syntax.uuid;
1383 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1384 if (iface == NULL) {
1385 char *uuid_str = GUID_string(call, &uuid);
1386 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1387 talloc_free(uuid_str);
1389 * We report this only via ack->result
1391 return NT_STATUS_OK;
1394 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1395 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1397 if (validate_only) {
1399 * We report this only via ack->result
1401 return NT_STATUS_OK;
1404 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1406 * we only do NDR encoded dcerpc for now.
1408 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1409 supported_transfer);
1411 selected_transfer = supported_transfer;
1416 context = dcesrv_find_context(call->conn, ctx->context_id);
1417 if (context != NULL) {
1418 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1419 &ctx->abstract_syntax);
1421 return NT_STATUS_RPC_PROTOCOL_ERROR;
1424 if (selected_transfer != NULL) {
1425 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1428 return NT_STATUS_RPC_PROTOCOL_ERROR;
1431 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1432 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1433 ack->syntax = context->transfer_syntax;
1437 * We report this only via ack->result
1439 return NT_STATUS_OK;
1442 if (selected_transfer == NULL) {
1444 * We report this only via ack->result
1446 return NT_STATUS_OK;
1449 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1450 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1452 /* add this context to the list of available context_ids */
1453 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1454 if (context == NULL) {
1455 return NT_STATUS_NO_MEMORY;
1457 context->conn = call->conn;
1458 context->context_id = ctx->context_id;
1459 context->iface = iface;
1460 context->transfer_syntax = *selected_transfer;
1461 context->private_data = NULL;
1462 DLIST_ADD(call->conn->contexts, context);
1463 call->context = context;
1464 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1466 dcesrv_prepare_context_auth(call);
1469 * Multiplex is supported by default
1471 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1473 status = iface->bind(call, iface, if_version);
1474 call->context = NULL;
1475 if (!NT_STATUS_IS_OK(status)) {
1476 /* we don't want to trigger the iface->unbind() hook */
1477 context->iface = NULL;
1478 talloc_free(context);
1480 * We report this only via ack->result
1482 return NT_STATUS_OK;
1485 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1486 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1487 ack->syntax = context->transfer_syntax;
1488 return NT_STATUS_OK;
1491 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1492 const struct dcerpc_bind *b,
1493 struct dcerpc_ack_ctx *ack_ctx_list)
1497 bool validate_only = false;
1498 bool preferred_ndr32;
1501 * Try to negotiate one new presentation context,
1502 * using our preferred transfer syntax.
1504 for (i = 0; i < b->num_contexts; i++) {
1505 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1506 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1508 status = dcesrv_check_or_create_context(call, b, c, a,
1510 call->conn->preferred_transfer);
1511 if (!NT_STATUS_IS_OK(status)) {
1515 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1517 * We managed to negotiate one context.
1521 validate_only = true;
1525 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1526 call->conn->preferred_transfer);
1527 if (preferred_ndr32) {
1531 return NT_STATUS_OK;
1535 * Try to negotiate one new presentation context,
1536 * using NDR 32 as fallback.
1538 for (i = 0; i < b->num_contexts; i++) {
1539 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1540 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1542 status = dcesrv_check_or_create_context(call, b, c, a,
1544 &ndr_transfer_syntax_ndr);
1545 if (!NT_STATUS_IS_OK(status)) {
1549 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1551 * We managed to negotiate one context.
1555 validate_only = true;
1559 return NT_STATUS_OK;
1562 static void dcesrv_alter_done(struct tevent_req *subreq);
1565 handle a alter context request
1567 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1569 struct dcesrv_connection *conn = call->conn;
1571 bool auth_ok = false;
1572 struct ncacn_packet *pkt = &call->ack_pkt;
1573 uint32_t extra_flags = 0;
1574 struct dcesrv_auth *auth = &call->conn->auth_state;
1575 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1576 struct tevent_req *subreq = NULL;
1579 if (!call->conn->allow_alter) {
1580 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1583 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1585 call->pkt.u.alter.auth_info.length,
1586 0, /* required flags */
1587 DCERPC_PFC_FLAG_FIRST |
1588 DCERPC_PFC_FLAG_LAST |
1589 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1590 0x08 | /* this is not defined, but should be ignored */
1591 DCERPC_PFC_FLAG_CONC_MPX |
1592 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1593 DCERPC_PFC_FLAG_MAYBE |
1594 DCERPC_PFC_FLAG_OBJECT_UUID);
1595 if (!NT_STATUS_IS_OK(status)) {
1596 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1599 auth_ok = dcesrv_auth_alter(call);
1601 if (call->fault_code != 0) {
1602 return dcesrv_fault_disconnect(call, call->fault_code);
1606 if (call->pkt.u.alter.num_contexts < 1) {
1607 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1610 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1611 call->pkt.u.alter.num_contexts);
1612 if (ack_ctx_list == NULL) {
1613 return NT_STATUS_NO_MEMORY;
1617 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1618 * dcesrv_check_or_create_context()) and do some protocol validation
1619 * and set sane defaults.
1621 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1622 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1623 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1625 if (c->num_transfer_syntaxes == 0) {
1626 return dcesrv_fault_disconnect(call,
1627 DCERPC_NCA_S_PROTO_ERROR);
1630 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1631 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1635 * Try to negotiate one new presentation context.
1637 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1638 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1639 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1641 if (!NT_STATUS_IS_OK(status)) {
1645 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1646 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1647 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1648 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1651 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1652 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1655 /* handle any authentication that is being requested */
1657 if (call->in_auth_info.auth_type !=
1658 call->conn->auth_state.auth_type)
1660 return dcesrv_fault_disconnect(call,
1661 DCERPC_FAULT_SEC_PKG_ERROR);
1663 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1666 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1667 pkt->auth_length = 0;
1668 pkt->call_id = call->pkt.call_id;
1669 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1670 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1671 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1672 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1673 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1674 pkt->u.alter_resp.secondary_address = "";
1675 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1676 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1677 pkt->u.alter_resp.auth_info = data_blob_null;
1679 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1680 if (!NT_STATUS_IS_OK(status)) {
1681 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1684 if (auth->auth_finished) {
1685 return dcesrv_auth_reply(call);
1688 subreq = gensec_update_send(call, call->event_ctx,
1689 auth->gensec_security,
1690 call->in_auth_info.credentials);
1691 if (subreq == NULL) {
1692 return NT_STATUS_NO_MEMORY;
1694 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1696 return dcesrv_conn_auth_wait_setup(conn);
1699 static void dcesrv_alter_done(struct tevent_req *subreq)
1701 struct dcesrv_call_state *call =
1702 tevent_req_callback_data(subreq,
1703 struct dcesrv_call_state);
1704 struct dcesrv_connection *conn = call->conn;
1707 status = gensec_update_recv(subreq, call,
1708 &call->out_auth_info->credentials);
1709 TALLOC_FREE(subreq);
1711 status = dcesrv_auth_complete(call, status);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1714 dcesrv_conn_auth_wait_finished(conn, status);
1718 status = dcesrv_auth_reply(call);
1719 dcesrv_conn_auth_wait_finished(conn, status);
1724 possibly save the call for inspection with ndrdump
1726 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1730 const char *dump_dir;
1731 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1735 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1737 call->context->iface->name,
1738 call->pkt.u.request.opnum,
1740 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1741 DEBUG(0,("RPC SAVED %s\n", fname));
1747 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1749 TALLOC_CTX *frame = talloc_stackframe();
1750 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1751 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1752 const struct dcerpc_sec_vt_pcontext pcontext = {
1753 .abstract_syntax = call->context->iface->syntax_id,
1754 .transfer_syntax = call->context->transfer_syntax,
1756 const struct dcerpc_sec_vt_header2 header2 =
1757 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1758 enum ndr_err_code ndr_err;
1759 struct dcerpc_sec_verification_trailer *vt = NULL;
1760 NTSTATUS status = NT_STATUS_OK;
1763 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1765 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1767 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1768 status = ndr_map_error2ntstatus(ndr_err);
1772 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1773 &pcontext, &header2);
1775 status = NT_STATUS_ACCESS_DENIED;
1784 handle a dcerpc request packet
1786 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1788 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1789 enum dcerpc_transport_t transport =
1790 dcerpc_binding_get_transport(endpoint->ep_description);
1791 struct ndr_pull *pull;
1794 if (!call->conn->allow_request) {
1795 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1798 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1799 if (call->conn->auth_state.gensec_security &&
1800 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1801 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1804 if (call->context == NULL) {
1805 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1806 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1809 switch (call->conn->auth_state.auth_level) {
1810 case DCERPC_AUTH_LEVEL_NONE:
1811 case DCERPC_AUTH_LEVEL_PACKET:
1812 case DCERPC_AUTH_LEVEL_INTEGRITY:
1813 case DCERPC_AUTH_LEVEL_PRIVACY:
1816 if (!call->context->allow_connect) {
1819 addr = tsocket_address_string(call->conn->remote_address,
1822 DEBUG(2, ("%s: restrict auth_level_connect access "
1823 "to [%s] with auth[type=0x%x,level=0x%x] "
1824 "on [%s] from [%s]\n",
1825 __func__, call->context->iface->name,
1826 call->conn->auth_state.auth_type,
1827 call->conn->auth_state.auth_level,
1828 derpc_transport_string_by_transport(transport),
1830 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1835 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1838 addr = tsocket_address_string(call->conn->remote_address, call);
1840 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1841 "to [%s] with auth[type=0x%x,level=0x%x] "
1842 "on [%s] from [%s]\n",
1844 call->context->min_auth_level,
1845 call->context->iface->name,
1846 call->conn->auth_state.auth_type,
1847 call->conn->auth_state.auth_level,
1848 derpc_transport_string_by_transport(transport),
1850 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1853 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1854 NT_STATUS_HAVE_NO_MEMORY(pull);
1856 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1858 call->ndr_pull = pull;
1860 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1861 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1864 status = dcesrv_check_verification_trailer(call);
1865 if (!NT_STATUS_IS_OK(status)) {
1866 uint32_t faultcode = DCERPC_FAULT_OTHER;
1867 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1868 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1870 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1871 nt_errstr(status)));
1872 return dcesrv_fault(call, faultcode);
1875 /* unravel the NDR for the packet */
1876 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1877 if (!NT_STATUS_IS_OK(status)) {
1878 uint8_t extra_flags = 0;
1879 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1880 /* we got an unknown call */
1881 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1882 call->pkt.u.request.opnum,
1883 call->context->iface->name));
1884 dcesrv_save_call(call, "unknown");
1885 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1887 dcesrv_save_call(call, "pullfail");
1889 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1892 if (pull->offset != pull->data_size) {
1893 dcesrv_save_call(call, "extrabytes");
1894 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1895 pull->data_size - pull->offset));
1898 /* call the dispatch function */
1899 status = call->context->iface->dispatch(call, call, call->r);
1900 if (!NT_STATUS_IS_OK(status)) {
1901 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1902 call->context->iface->name,
1903 call->pkt.u.request.opnum,
1904 dcerpc_errstr(pull, call->fault_code)));
1905 return dcesrv_fault(call, call->fault_code);
1908 /* add the call to the pending list */
1909 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1911 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1912 return NT_STATUS_OK;
1915 return dcesrv_reply(call);
1920 remove the call from the right list when freed
1922 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1924 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1928 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1930 return conn->local_address;
1933 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1935 return conn->remote_address;
1939 process some input to a dcerpc endpoint server.
1941 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1942 struct ncacn_packet *pkt,
1946 struct dcesrv_call_state *call;
1947 struct dcesrv_call_state *existing = NULL;
1949 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1951 data_blob_free(&blob);
1953 return NT_STATUS_NO_MEMORY;
1955 call->conn = dce_conn;
1956 call->event_ctx = dce_conn->event_ctx;
1957 call->msg_ctx = dce_conn->msg_ctx;
1958 call->state_flags = call->conn->state_flags;
1959 call->time = timeval_current();
1960 call->list = DCESRV_LIST_NONE;
1962 talloc_steal(call, pkt);
1963 talloc_steal(call, blob.data);
1966 talloc_set_destructor(call, dcesrv_call_dequeue);
1968 if (call->conn->allow_bind) {
1970 * Only one bind is possible per connection
1972 call->conn->allow_bind = false;
1973 return dcesrv_bind(call);
1976 /* we have to check the signing here, before combining the
1978 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1979 if (!call->conn->allow_request) {
1980 return dcesrv_fault_disconnect(call,
1981 DCERPC_NCA_S_PROTO_ERROR);
1984 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1986 call->pkt.u.request.stub_and_verifier.length,
1987 0, /* required_flags */
1988 DCERPC_PFC_FLAG_FIRST |
1989 DCERPC_PFC_FLAG_LAST |
1990 DCERPC_PFC_FLAG_PENDING_CANCEL |
1991 0x08 | /* this is not defined, but should be ignored */
1992 DCERPC_PFC_FLAG_CONC_MPX |
1993 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1994 DCERPC_PFC_FLAG_MAYBE |
1995 DCERPC_PFC_FLAG_OBJECT_UUID);
1996 if (!NT_STATUS_IS_OK(status)) {
1997 return dcesrv_fault_disconnect(call,
1998 DCERPC_NCA_S_PROTO_ERROR);
2001 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2003 * We don't use dcesrv_fault_disconnect()
2004 * here, because we don't want to set
2005 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2007 * Note that we don't check against the negotiated
2008 * max_recv_frag, but a hard coded value.
2010 dcesrv_call_disconnect_after(call,
2011 "dcesrv_auth_request - frag_length too large");
2012 return dcesrv_fault(call,
2013 DCERPC_NCA_S_PROTO_ERROR);
2016 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2017 if (dce_conn->pending_call_list != NULL) {
2019 * concurrent requests are only allowed
2020 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2022 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2023 dcesrv_call_disconnect_after(call,
2024 "dcesrv_auth_request - "
2025 "existing pending call without CONN_MPX");
2026 return dcesrv_fault(call,
2027 DCERPC_NCA_S_PROTO_ERROR);
2030 /* only one request is possible in the fragmented list */
2031 if (dce_conn->incoming_fragmented_call_list != NULL) {
2032 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2034 * Without DCERPC_PFC_FLAG_CONC_MPX
2035 * we need to return the FAULT on the
2036 * already existing call.
2038 * This is important to get the
2039 * call_id and context_id right.
2042 call = dce_conn->incoming_fragmented_call_list;
2044 dcesrv_call_disconnect_after(call,
2045 "dcesrv_auth_request - "
2046 "existing fragmented call");
2047 return dcesrv_fault(call,
2048 DCERPC_NCA_S_PROTO_ERROR);
2050 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2051 return dcesrv_fault_disconnect(call,
2052 DCERPC_FAULT_NO_CALL_ACTIVE);
2054 call->context = dcesrv_find_context(call->conn,
2055 call->pkt.u.request.context_id);
2056 if (call->context == NULL) {
2057 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2058 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2061 const struct dcerpc_request *nr = &call->pkt.u.request;
2062 const struct dcerpc_request *er = NULL;
2065 existing = dcesrv_find_fragmented_call(dce_conn,
2067 if (existing == NULL) {
2068 dcesrv_call_disconnect_after(call,
2069 "dcesrv_auth_request - "
2070 "no existing fragmented call");
2071 return dcesrv_fault(call,
2072 DCERPC_NCA_S_PROTO_ERROR);
2074 er = &existing->pkt.u.request;
2076 if (call->pkt.ptype != existing->pkt.ptype) {
2077 /* trying to play silly buggers are we? */
2078 return dcesrv_fault_disconnect(existing,
2079 DCERPC_NCA_S_PROTO_ERROR);
2081 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2084 return dcesrv_fault_disconnect(existing,
2085 DCERPC_NCA_S_PROTO_ERROR);
2087 if (nr->context_id != er->context_id) {
2088 return dcesrv_fault_disconnect(existing,
2089 DCERPC_NCA_S_PROTO_ERROR);
2091 if (nr->opnum != er->opnum) {
2092 return dcesrv_fault_disconnect(existing,
2093 DCERPC_NCA_S_PROTO_ERROR);
2098 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2100 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2102 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2103 payload_offset += 16;
2106 ok = dcesrv_auth_pkt_pull(call, &blob,
2107 0, /* required_flags */
2108 DCERPC_PFC_FLAG_FIRST |
2109 DCERPC_PFC_FLAG_LAST |
2110 DCERPC_PFC_FLAG_PENDING_CANCEL |
2111 0x08 | /* this is not defined, but should be ignored */
2112 DCERPC_PFC_FLAG_CONC_MPX |
2113 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2114 DCERPC_PFC_FLAG_MAYBE |
2115 DCERPC_PFC_FLAG_OBJECT_UUID,
2117 &call->pkt.u.request.stub_and_verifier);
2120 * We don't use dcesrv_fault_disconnect()
2121 * here, because we don't want to set
2122 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2124 dcesrv_call_disconnect_after(call,
2125 "dcesrv_auth_request - failed");
2126 if (call->fault_code == 0) {
2127 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2129 return dcesrv_fault(call, call->fault_code);
2133 /* see if this is a continued packet */
2134 if (existing != NULL) {
2135 struct dcerpc_request *er = &existing->pkt.u.request;
2136 const struct dcerpc_request *nr = &call->pkt.u.request;
2142 * Up to 4 MByte are allowed by all fragments
2144 available = dce_conn->max_total_request_size;
2145 if (er->stub_and_verifier.length > available) {
2146 dcesrv_call_disconnect_after(existing,
2147 "dcesrv_auth_request - existing payload too large");
2148 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2150 available -= er->stub_and_verifier.length;
2151 if (nr->alloc_hint > available) {
2152 dcesrv_call_disconnect_after(existing,
2153 "dcesrv_auth_request - alloc hint too large");
2154 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2156 if (nr->stub_and_verifier.length > available) {
2157 dcesrv_call_disconnect_after(existing,
2158 "dcesrv_auth_request - new payload too large");
2159 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2161 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2162 /* allocate at least 1 byte */
2163 alloc_hint = MAX(alloc_hint, 1);
2164 alloc_size = er->stub_and_verifier.length +
2165 nr->stub_and_verifier.length;
2166 alloc_size = MAX(alloc_size, alloc_hint);
2168 er->stub_and_verifier.data =
2169 talloc_realloc(existing,
2170 er->stub_and_verifier.data,
2171 uint8_t, alloc_size);
2172 if (er->stub_and_verifier.data == NULL) {
2174 return dcesrv_fault_with_flags(existing,
2175 DCERPC_FAULT_OUT_OF_RESOURCES,
2176 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2178 memcpy(er->stub_and_verifier.data +
2179 er->stub_and_verifier.length,
2180 nr->stub_and_verifier.data,
2181 nr->stub_and_verifier.length);
2182 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2184 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2190 /* this may not be the last pdu in the chain - if its isn't then
2191 just put it on the incoming_fragmented_call_list and wait for the rest */
2192 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2193 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2195 * Up to 4 MByte are allowed by all fragments
2197 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2198 dcesrv_call_disconnect_after(call,
2199 "dcesrv_auth_request - initial alloc hint too large");
2200 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2202 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2203 return NT_STATUS_OK;
2206 /* This removes any fragments we may have had stashed away */
2207 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2209 switch (call->pkt.ptype) {
2210 case DCERPC_PKT_BIND:
2211 status = dcesrv_bind_nak(call,
2212 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2214 case DCERPC_PKT_AUTH3:
2215 status = dcesrv_auth3(call);
2217 case DCERPC_PKT_ALTER:
2218 status = dcesrv_alter(call);
2220 case DCERPC_PKT_REQUEST:
2221 status = dcesrv_request(call);
2223 case DCERPC_PKT_CO_CANCEL:
2224 case DCERPC_PKT_ORPHANED:
2226 * Window just ignores CO_CANCEL and ORPHANED,
2229 status = NT_STATUS_OK;
2232 case DCERPC_PKT_BIND_ACK:
2233 case DCERPC_PKT_BIND_NAK:
2234 case DCERPC_PKT_ALTER_RESP:
2235 case DCERPC_PKT_RESPONSE:
2236 case DCERPC_PKT_FAULT:
2237 case DCERPC_PKT_SHUTDOWN:
2239 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2243 /* if we are going to be sending a reply then add
2244 it to the list of pending calls. We add it to the end to keep the call
2245 list in the order we will answer */
2246 if (!NT_STATUS_IS_OK(status)) {
2253 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2254 struct loadparm_context *lp_ctx,
2255 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2258 struct dcesrv_context *dce_ctx;
2261 if (!endpoint_servers) {
2262 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2263 return NT_STATUS_INTERNAL_ERROR;
2266 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2267 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2269 if (uid_wrapper_enabled()) {
2270 setenv("UID_WRAPPER_MYUID", "1", 1);
2272 dce_ctx->initial_euid = geteuid();
2273 if (uid_wrapper_enabled()) {
2274 unsetenv("UID_WRAPPER_MYUID");
2277 dce_ctx->endpoint_list = NULL;
2278 dce_ctx->lp_ctx = lp_ctx;
2279 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2280 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2281 dce_ctx->broken_connections = NULL;
2283 for (i=0;endpoint_servers[i];i++) {
2284 const struct dcesrv_endpoint_server *ep_server;
2286 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2288 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2289 return NT_STATUS_INTERNAL_ERROR;
2292 status = ep_server->init_server(dce_ctx, ep_server);
2293 if (!NT_STATUS_IS_OK(status)) {
2294 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2295 nt_errstr(status)));
2300 *_dce_ctx = dce_ctx;
2301 return NT_STATUS_OK;
2304 /* the list of currently registered DCERPC endpoint servers.
2306 static struct ep_server {
2307 struct dcesrv_endpoint_server *ep_server;
2308 } *ep_servers = NULL;
2309 static int num_ep_servers;
2312 register a DCERPC endpoint server.
2314 The 'name' can be later used by other backends to find the operations
2315 structure for this backend.
2318 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2321 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2322 /* its already registered! */
2323 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2325 return NT_STATUS_OBJECT_NAME_COLLISION;
2328 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2330 smb_panic("out of memory in dcerpc_register");
2333 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2334 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2338 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2341 return NT_STATUS_OK;
2345 return the operations structure for a named backend of the specified type
2347 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2351 for (i=0;i<num_ep_servers;i++) {
2352 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2353 return ep_servers[i].ep_server;
2360 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2362 static bool initialized;
2363 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2364 STATIC_dcerpc_server_MODULES_PROTO;
2365 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2366 init_module_fn *shared_init;
2373 shared_init = load_samba_modules(NULL, "dcerpc_server");
2375 run_init_functions(NULL, static_init);
2376 run_init_functions(NULL, shared_init);
2378 talloc_free(shared_init);
2382 return the DCERPC module version, and the size of some critical types
2383 This can be used by endpoint server modules to either detect compilation errors, or provide
2384 multiple implementations for different smbd compilation options in one module
2386 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2388 static const struct dcesrv_critical_sizes critical_sizes = {
2389 DCERPC_MODULE_VERSION,
2390 sizeof(struct dcesrv_context),
2391 sizeof(struct dcesrv_endpoint),
2392 sizeof(struct dcesrv_endpoint_server),
2393 sizeof(struct dcesrv_interface),
2394 sizeof(struct dcesrv_if_list),
2395 sizeof(struct dcesrv_connection),
2396 sizeof(struct dcesrv_call_state),
2397 sizeof(struct dcesrv_auth),
2398 sizeof(struct dcesrv_handle)
2401 return &critical_sizes;
2404 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2406 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2407 struct stream_connection *srv_conn;
2408 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2409 struct stream_connection);
2411 dce_conn->wait_send = NULL;
2412 dce_conn->wait_recv = NULL;
2413 dce_conn->wait_private = NULL;
2415 dce_conn->allow_bind = false;
2416 dce_conn->allow_auth3 = false;
2417 dce_conn->allow_alter = false;
2418 dce_conn->allow_request = false;
2420 if (dce_conn->pending_call_list == NULL) {
2421 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2423 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2424 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2428 if (dce_conn->terminate != NULL) {
2432 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2434 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2435 if (dce_conn->terminate == NULL) {
2436 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2438 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2441 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2443 struct dcesrv_connection *cur, *next;
2445 next = dce_ctx->broken_connections;
2446 while (next != NULL) {
2450 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2451 struct dcesrv_connection_context *context_cur, *context_next;
2453 context_next = cur->contexts;
2454 while (context_next != NULL) {
2455 context_cur = context_next;
2456 context_next = context_cur->next;
2458 dcesrv_connection_context_destructor(context_cur);
2462 dcesrv_terminate_connection(cur, cur->terminate);
2466 /* We need this include to be able to compile on some plateforms
2467 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2469 * It has to be that deep because otherwise we have a conflict on
2470 * const struct dcesrv_interface declaration.
2471 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2472 * which conflict with the bind used before.
2474 #include "system/network.h"
2476 struct dcesrv_sock_reply_state {
2477 struct dcesrv_connection *dce_conn;
2478 struct dcesrv_call_state *call;
2482 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2483 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2485 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2487 struct dcesrv_call_state *call;
2489 call = dce_conn->call_list;
2490 if (!call || !call->replies) {
2494 while (call->replies) {
2495 struct data_blob_list_item *rep = call->replies;
2496 struct dcesrv_sock_reply_state *substate;
2497 struct tevent_req *subreq;
2499 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2501 dcesrv_terminate_connection(dce_conn, "no memory");
2505 substate->dce_conn = dce_conn;
2506 substate->call = NULL;
2508 DLIST_REMOVE(call->replies, rep);
2510 if (call->replies == NULL && call->terminate_reason == NULL) {
2511 substate->call = call;
2514 substate->iov.iov_base = (void *) rep->blob.data;
2515 substate->iov.iov_len = rep->blob.length;
2517 subreq = tstream_writev_queue_send(substate,
2518 dce_conn->event_ctx,
2520 dce_conn->send_queue,
2523 dcesrv_terminate_connection(dce_conn, "no memory");
2526 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2530 if (call->terminate_reason != NULL) {
2531 struct tevent_req *subreq;
2533 subreq = tevent_queue_wait_send(call,
2534 dce_conn->event_ctx,
2535 dce_conn->send_queue);
2537 dcesrv_terminate_connection(dce_conn, __location__);
2540 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2544 DLIST_REMOVE(call->conn->call_list, call);
2545 call->list = DCESRV_LIST_NONE;
2548 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2550 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2551 struct dcesrv_sock_reply_state);
2555 struct dcesrv_call_state *call = substate->call;
2557 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2558 TALLOC_FREE(subreq);
2560 status = map_nt_error_from_unix_common(sys_errno);
2561 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2565 talloc_free(substate);
2571 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2573 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2575 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2576 struct dcesrv_call_state);
2580 /* make sure we stop send queue before removing subreq */
2581 tevent_queue_stop(call->conn->send_queue);
2583 ok = tevent_queue_wait_recv(subreq);
2584 TALLOC_FREE(subreq);
2586 dcesrv_terminate_connection(call->conn, __location__);
2590 /* disconnect after 200 usecs */
2591 tv = timeval_current_ofs_usec(200);
2592 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2593 if (subreq == NULL) {
2594 dcesrv_terminate_connection(call->conn, __location__);
2597 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2601 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2603 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2604 struct dcesrv_call_state);
2607 ok = tevent_wakeup_recv(subreq);
2608 TALLOC_FREE(subreq);
2610 dcesrv_terminate_connection(call->conn, __location__);
2614 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2617 struct dcesrv_socket_context {
2618 const struct dcesrv_endpoint *endpoint;
2619 struct dcesrv_context *dcesrv_ctx;
2623 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2625 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2628 struct dcesrv_socket_context *dcesrv_sock =
2629 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2630 enum dcerpc_transport_t transport =
2631 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2632 struct dcesrv_connection *dcesrv_conn = NULL;
2634 struct tevent_req *subreq;
2635 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2637 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2639 if (!srv_conn->session_info) {
2640 status = auth_anonymous_session_info(srv_conn,
2642 &srv_conn->session_info);
2643 if (!NT_STATUS_IS_OK(status)) {
2644 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2645 nt_errstr(status)));
2646 stream_terminate_connection(srv_conn, nt_errstr(status));
2652 * This fills in dcesrv_conn->endpoint with the endpoint
2653 * associated with the socket. From this point on we know
2654 * which (group of) services we are handling, but not the
2655 * specific interface.
2658 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2660 dcesrv_sock->endpoint,
2661 srv_conn->session_info,
2662 srv_conn->event.ctx,
2664 srv_conn->server_id,
2665 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2667 if (!NT_STATUS_IS_OK(status)) {
2668 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2669 nt_errstr(status)));
2670 stream_terminate_connection(srv_conn, nt_errstr(status));
2674 dcesrv_conn->transport.private_data = srv_conn;
2675 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2677 TALLOC_FREE(srv_conn->event.fde);
2679 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2680 if (!dcesrv_conn->send_queue) {
2681 status = NT_STATUS_NO_MEMORY;
2682 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2683 nt_errstr(status)));
2684 stream_terminate_connection(srv_conn, nt_errstr(status));
2688 if (transport == NCACN_NP) {
2689 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2690 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2691 &srv_conn->tstream);
2693 ret = tstream_bsd_existing_socket(dcesrv_conn,
2694 socket_get_fd(srv_conn->socket),
2695 &dcesrv_conn->stream);
2697 status = map_nt_error_from_unix_common(errno);
2698 DEBUG(0, ("dcesrv_sock_accept: "
2699 "failed to setup tstream: %s\n",
2700 nt_errstr(status)));
2701 stream_terminate_connection(srv_conn, nt_errstr(status));
2704 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2707 dcesrv_conn->local_address = srv_conn->local_address;
2708 dcesrv_conn->remote_address = srv_conn->remote_address;
2710 if (transport == NCALRPC) {
2715 sock_fd = socket_get_fd(srv_conn->socket);
2716 if (sock_fd == -1) {
2717 stream_terminate_connection(
2718 srv_conn, "socket_get_fd failed\n");
2722 ret = getpeereid(sock_fd, &uid, &gid);
2724 status = map_nt_error_from_unix_common(errno);
2725 DEBUG(0, ("dcesrv_sock_accept: "
2726 "getpeereid() failed for NCALRPC: %s\n",
2727 nt_errstr(status)));
2728 stream_terminate_connection(srv_conn, nt_errstr(status));
2731 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2732 struct tsocket_address *r = NULL;
2734 ret = tsocket_address_unix_from_path(dcesrv_conn,
2735 AS_SYSTEM_MAGIC_PATH_TOKEN,
2738 status = map_nt_error_from_unix_common(errno);
2739 DEBUG(0, ("dcesrv_sock_accept: "
2740 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2741 nt_errstr(status)));
2742 stream_terminate_connection(srv_conn, nt_errstr(status));
2745 dcesrv_conn->remote_address = r;
2749 srv_conn->private_data = dcesrv_conn;
2751 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2752 dcesrv_conn->event_ctx,
2753 dcesrv_conn->stream);
2755 status = NT_STATUS_NO_MEMORY;
2756 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2757 nt_errstr(status)));
2758 stream_terminate_connection(srv_conn, nt_errstr(status));
2761 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2766 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2768 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2770 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2771 struct dcesrv_connection);
2772 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2773 struct ncacn_packet *pkt;
2777 if (dce_conn->terminate) {
2779 * if the current connection is broken
2780 * we need to clean it up before any other connection
2782 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2783 dcesrv_cleanup_broken_connections(dce_ctx);
2787 dcesrv_cleanup_broken_connections(dce_ctx);
2789 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2791 TALLOC_FREE(subreq);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2797 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2798 if (!NT_STATUS_IS_OK(status)) {
2799 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2804 * This is used to block the connection during
2805 * pending authentication.
2807 if (dce_conn->wait_send != NULL) {
2808 subreq = dce_conn->wait_send(dce_conn,
2809 dce_conn->event_ctx,
2810 dce_conn->wait_private);
2812 status = NT_STATUS_NO_MEMORY;
2813 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2816 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2820 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2821 dce_conn->event_ctx,
2824 status = NT_STATUS_NO_MEMORY;
2825 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2828 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2831 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2833 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2834 struct dcesrv_connection);
2835 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2838 if (dce_conn->terminate) {
2840 * if the current connection is broken
2841 * we need to clean it up before any other connection
2843 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2844 dcesrv_cleanup_broken_connections(dce_ctx);
2848 dcesrv_cleanup_broken_connections(dce_ctx);
2850 status = dce_conn->wait_recv(subreq);
2851 dce_conn->wait_send = NULL;
2852 dce_conn->wait_recv = NULL;
2853 dce_conn->wait_private = NULL;
2854 TALLOC_FREE(subreq);
2855 if (!NT_STATUS_IS_OK(status)) {
2856 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2860 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2861 dce_conn->event_ctx,
2864 status = NT_STATUS_NO_MEMORY;
2865 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2868 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2871 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2873 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2874 struct dcesrv_connection);
2875 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2878 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2880 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2881 struct dcesrv_connection);
2882 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2886 static const struct stream_server_ops dcesrv_stream_ops = {
2888 .accept_connection = dcesrv_sock_accept,
2889 .recv_handler = dcesrv_sock_recv,
2890 .send_handler = dcesrv_sock_send,
2893 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2894 struct loadparm_context *lp_ctx,
2895 struct dcesrv_endpoint *e,
2896 struct tevent_context *event_ctx,
2897 const struct model_ops *model_ops,
2898 void *process_context)
2900 struct dcesrv_socket_context *dcesrv_sock;
2903 const char *endpoint;
2905 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2906 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2908 /* remember the endpoint of this socket */
2909 dcesrv_sock->endpoint = e;
2910 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2912 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2914 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2915 model_ops, &dcesrv_stream_ops,
2916 "unix", endpoint, &port,
2917 lpcfg_socket_options(lp_ctx),
2918 dcesrv_sock, process_context);
2919 if (!NT_STATUS_IS_OK(status)) {
2920 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2921 endpoint, nt_errstr(status)));
2927 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2928 struct loadparm_context *lp_ctx,
2929 struct dcesrv_endpoint *e,
2930 struct tevent_context *event_ctx,
2931 const struct model_ops *model_ops,
2932 void *process_context)
2934 struct dcesrv_socket_context *dcesrv_sock;
2938 const char *endpoint;
2940 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2942 if (endpoint == NULL) {
2944 * No identifier specified: use DEFAULT.
2946 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2947 * no endpoint and let the epmapper worry about it.
2949 endpoint = "DEFAULT";
2950 status = dcerpc_binding_set_string_option(e->ep_description,
2953 if (!NT_STATUS_IS_OK(status)) {
2954 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2955 nt_errstr(status)));
2960 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2963 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2964 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2966 /* remember the endpoint of this socket */
2967 dcesrv_sock->endpoint = e;
2968 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2970 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2971 model_ops, &dcesrv_stream_ops,
2972 "unix", full_path, &port,
2973 lpcfg_socket_options(lp_ctx),
2974 dcesrv_sock, process_context);
2975 if (!NT_STATUS_IS_OK(status)) {
2976 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2977 endpoint, full_path, nt_errstr(status)));
2982 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2983 struct loadparm_context *lp_ctx,
2984 struct dcesrv_endpoint *e,
2985 struct tevent_context *event_ctx,
2986 const struct model_ops *model_ops,
2987 void *process_context)
2989 struct dcesrv_socket_context *dcesrv_sock;
2991 const char *endpoint;
2993 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2994 if (endpoint == NULL) {
2995 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2996 return NT_STATUS_INVALID_PARAMETER;
2999 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3000 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3002 /* remember the endpoint of this socket */
3003 dcesrv_sock->endpoint = e;
3004 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3006 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3007 model_ops, &dcesrv_stream_ops,
3009 dcesrv_sock, process_context);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3012 endpoint, nt_errstr(status)));
3016 return NT_STATUS_OK;
3020 add a socket address to the list of events, one event per dcerpc endpoint
3022 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3023 struct dcesrv_endpoint *e,
3024 struct tevent_context *event_ctx,
3025 const struct model_ops *model_ops,
3026 const char *address,
3027 void *process_context)
3029 struct dcesrv_socket_context *dcesrv_sock;
3032 const char *endpoint;
3035 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3036 if (endpoint != NULL) {
3037 port = atoi(endpoint);
3040 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3041 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3043 /* remember the endpoint of this socket */
3044 dcesrv_sock->endpoint = e;
3045 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3047 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3048 model_ops, &dcesrv_stream_ops,
3049 "ip", address, &port,
3050 lpcfg_socket_options(dce_ctx->lp_ctx),
3051 dcesrv_sock, process_context);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 struct dcesrv_if_list *iface;
3054 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3056 for (iface = e->interface_list; iface; iface = iface->next) {
3057 DEBUGADD(0, ("%s ", iface->iface.name));
3059 DEBUGADD(0, ("failed - %s",
3060 nt_errstr(status)));
3064 snprintf(port_str, sizeof(port_str), "%u", port);
3066 status = dcerpc_binding_set_string_option(e->ep_description,
3067 "endpoint", port_str);
3068 if (!NT_STATUS_IS_OK(status)) {
3069 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3070 port_str, nt_errstr(status)));
3073 struct dcesrv_if_list *iface;
3074 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3075 address, port_str));
3076 for (iface = e->interface_list; iface; iface = iface->next) {
3077 DEBUGADD(4, ("%s ", iface->iface.name));
3079 DEBUGADD(4, ("\n"));
3082 return NT_STATUS_OK;
3085 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3087 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3088 struct loadparm_context *lp_ctx,
3089 struct dcesrv_endpoint *e,
3090 struct tevent_context *event_ctx,
3091 const struct model_ops *model_ops,
3092 void *process_context)
3096 /* Add TCP/IP sockets */
3097 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3100 struct interface *ifaces;
3102 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3104 num_interfaces = iface_list_count(ifaces);
3105 for(i = 0; i < num_interfaces; i++) {
3106 const char *address = iface_list_n_ip(ifaces, i);
3107 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3110 NT_STATUS_NOT_OK_RETURN(status);
3115 size_t num_binds = 0;
3116 wcard = iface_list_wildcard(dce_ctx);
3117 NT_STATUS_HAVE_NO_MEMORY(wcard);
3118 for (i=0; wcard[i]; i++) {
3119 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3120 model_ops, wcard[i],
3122 if (NT_STATUS_IS_OK(status)) {
3127 if (num_binds == 0) {
3128 return NT_STATUS_INVALID_PARAMETER_MIX;
3132 return NT_STATUS_OK;
3135 NTSTATUS dcesrv_add_ep(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)
3142 enum dcerpc_transport_t transport =
3143 dcerpc_binding_get_transport(e->ep_description);
3145 switch (transport) {
3146 case NCACN_UNIX_STREAM:
3147 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3148 model_ops, process_context);
3151 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3152 model_ops, process_context);
3155 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3156 model_ops, process_context);
3159 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3160 model_ops, process_context);
3163 return NT_STATUS_NOT_SUPPORTED;
3169 * retrieve credentials from a dce_call
3171 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3173 return dce_call->conn->auth_state.session_info->credentials;
3177 * returns true if this is an authenticated call
3179 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3181 enum security_user_level level;
3182 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3183 return level >= SECURITY_USER;
3187 * retrieve account_name for a dce_call
3189 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3191 return dce_call->context->conn->auth_state.session_info->info->account_name;
3195 * retrieve session_info from a dce_call
3197 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3199 return dce_call->context->conn->auth_state.session_info;