s4:rpc_server: replace dce_conn->allow_request with auth->auth_finished
[Samba.git] / source4 / rpc_server / dcerpc_server.c
blobe763b581f4d4ba19a42ad5906605d814950db51b
1 /*
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/>.
23 #include "includes.h"
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,
54 uint32_t id)
56 void *id_ptr;
58 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
59 if (id_ptr == NULL) {
60 return NULL;
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,
70 uint32_t id)
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));
77 return NULL;
79 return talloc_reference(mem_ctx, assoc_group);
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
84 int ret;
85 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
86 if (ret != 0) {
87 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
88 assoc_group->id));
90 return 0;
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;
100 int id;
102 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103 if (assoc_group == NULL) {
104 return NULL;
107 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
108 if (id == -1) {
109 talloc_free(assoc_group);
110 DEBUG(0,(__location__ ": Out of association groups!\n"));
111 return NULL;
114 assoc_group->id = id;
115 assoc_group->dce_ctx = dce_ctx;
117 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
119 return assoc_group;
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;
131 const char *e1;
132 const char *e2;
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");
140 if (t1 != t2) {
141 return false;
144 if (!e1 || !e2) {
145 return e1 == e2;
148 if (strcasecmp(e1, e2) != 0) {
149 return false;
152 return true;
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)) {
164 return ep;
167 return NULL;
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,
174 uint16_t context_id)
176 struct dcesrv_connection_context *c;
177 for (c=conn->contexts;c;c=c->next) {
178 if (c->context_id == context_id) return c;
180 return NULL;
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);
211 return NULL;
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);
236 return NULL;
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) {
247 return c;
250 return NULL;
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,
266 const char *ep_name,
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;
273 bool add_ep = false;
274 NTSTATUS status;
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
287 * ncalrpc.
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));
297 return status;
300 transport = dcerpc_binding_get_transport(binding);
301 if (transport == NCACN_IP_TCP) {
302 int port;
303 char port_str[6];
306 * First check if there is already a port specified, eg
307 * for epmapper on ncacn_ip_tcp:[135]
309 const char *endpoint
310 = dcerpc_binding_get_string_option(binding,
311 "endpoint");
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
320 * that port.
322 if (port == 0 && !use_single_process) {
323 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
325 if (port != 0) {
326 snprintf(port_str, sizeof(port_str), "%u", port);
327 status = dcerpc_binding_set_string_option(binding,
328 "endpoint",
329 port_str);
330 if (!NT_STATUS_IS_OK(status)) {
331 return 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);
348 if (ep != NULL) {
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
357 * 1024).
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) {
367 add_ep = true;
371 if (ep == NULL || add_ep) {
372 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
373 if (!ep) {
374 return NT_STATUS_NO_MEMORY;
376 ZERO_STRUCTP(ep);
377 ep->ep_description = talloc_move(ep, &binding);
378 add_ep = true;
380 /* add mgmt interface */
381 ifl = talloc_zero(ep, struct dcesrv_if_list);
382 if (!ifl) {
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);
405 if (!ifl) {
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
415 if (sd != NULL) {
416 /* if there's currently no security descriptor given on the endpoint
417 * we try to set it
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);
432 free(ifl);
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 */
441 if (add_ep) {
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";
450 } else {
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);
459 return NT_STATUS_OK;
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;
474 return NT_STATUS_OK;
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;
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;
518 NTSTATUS status;
520 if (auth->session_key_fn == NULL) {
521 return NT_STATUS_NO_USER_SESSION_KEY;
524 status = auth->session_key_fn(auth, session_key);
525 if (!NT_STATUS_IS_OK(status)) {
526 return status;
529 session_key->length = MIN(session_key->length, 16);
531 return NT_STATUS_OK;
534 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
536 const struct dcesrv_endpoint *ep = conn->endpoint;
537 enum dcerpc_transport_t transport =
538 dcerpc_binding_get_transport(ep->ep_description);
539 struct dcesrv_auth *auth = NULL;
541 auth = talloc_zero(conn, struct dcesrv_auth);
542 if (auth == NULL) {
543 return NULL;
546 switch (transport) {
547 case NCACN_NP:
548 auth->session_key_fn = dcesrv_remote_session_key;
549 break;
550 case NCALRPC:
551 case NCACN_UNIX_STREAM:
552 auth->session_key_fn = dcesrv_local_fixed_session_key;
553 break;
554 default:
556 * All other's get a NULL pointer, which
557 * results in NT_STATUS_NO_USER_SESSION_KEY
559 break;
562 return auth;
566 connect to a dcerpc endpoint
568 static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
569 TALLOC_CTX *mem_ctx,
570 const struct dcesrv_endpoint *ep,
571 struct auth_session_info *session_info,
572 struct tevent_context *event_ctx,
573 struct imessaging_context *msg_ctx,
574 struct server_id server_id,
575 uint32_t state_flags,
576 struct dcesrv_connection **_p)
578 struct dcesrv_auth *auth = NULL;
579 struct dcesrv_connection *p;
581 if (!session_info) {
582 return NT_STATUS_ACCESS_DENIED;
585 p = talloc_zero(mem_ctx, struct dcesrv_connection);
586 NT_STATUS_HAVE_NO_MEMORY(p);
588 p->dce_ctx = dce_ctx;
589 p->endpoint = ep;
590 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
591 p->event_ctx = event_ctx;
592 p->msg_ctx = msg_ctx;
593 p->server_id = server_id;
594 p->state_flags = state_flags;
595 p->allow_bind = true;
596 p->max_recv_frag = 5840;
597 p->max_xmit_frag = 5840;
598 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
600 auth = dcesrv_auth_create(p);
601 if (auth == NULL) {
602 talloc_free(p);
603 return NT_STATUS_NO_MEMORY;
606 auth->session_info = talloc_reference(auth, session_info);
607 if (auth->session_info == NULL) {
608 talloc_free(p);
609 return NT_STATUS_NO_MEMORY;
612 p->default_auth_state = auth;
615 * For now we only support NDR32.
617 p->preferred_transfer = &ndr_transfer_syntax_ndr;
619 *_p = p;
620 return NT_STATUS_OK;
624 move a call from an existing linked list to the specified list. This
625 prevents bugs where we forget to remove the call from a previous
626 list when moving it.
628 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
629 enum dcesrv_call_list list)
631 switch (call->list) {
632 case DCESRV_LIST_NONE:
633 break;
634 case DCESRV_LIST_CALL_LIST:
635 DLIST_REMOVE(call->conn->call_list, call);
636 break;
637 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
638 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
639 break;
640 case DCESRV_LIST_PENDING_CALL_LIST:
641 DLIST_REMOVE(call->conn->pending_call_list, call);
642 break;
644 call->list = list;
645 switch (list) {
646 case DCESRV_LIST_NONE:
647 break;
648 case DCESRV_LIST_CALL_LIST:
649 DLIST_ADD_END(call->conn->call_list, call);
650 break;
651 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
652 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
653 break;
654 case DCESRV_LIST_PENDING_CALL_LIST:
655 DLIST_ADD_END(call->conn->pending_call_list, call);
656 break;
660 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
661 const char *reason)
663 if (call->conn->terminate != NULL) {
664 return;
667 call->conn->allow_bind = false;
668 call->conn->allow_alter = false;
670 call->conn->default_auth_state->auth_invalid = true;
672 call->terminate_reason = talloc_strdup(call, reason);
673 if (call->terminate_reason == NULL) {
674 call->terminate_reason = __location__;
679 return a dcerpc bind_nak
681 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
683 struct ncacn_packet pkt;
684 struct dcerpc_bind_nak_version version;
685 struct data_blob_list_item *rep;
686 NTSTATUS status;
687 static const uint8_t _pad[3] = { 0, };
690 * We add the call to the pending_call_list
691 * in order to defer the termination.
693 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
695 /* setup a bind_nak */
696 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
697 pkt.auth_length = 0;
698 pkt.call_id = call->pkt.call_id;
699 pkt.ptype = DCERPC_PKT_BIND_NAK;
700 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
701 pkt.u.bind_nak.reject_reason = reason;
702 version.rpc_vers = 5;
703 version.rpc_vers_minor = 0;
704 pkt.u.bind_nak.num_versions = 1;
705 pkt.u.bind_nak.versions = &version;
706 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
708 rep = talloc_zero(call, struct data_blob_list_item);
709 if (!rep) {
710 return NT_STATUS_NO_MEMORY;
713 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
714 if (!NT_STATUS_IS_OK(status)) {
715 return status;
718 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
720 DLIST_ADD_END(call->replies, rep);
721 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
723 if (call->conn->call_list && call->conn->call_list->replies) {
724 if (call->conn->transport.report_output_data) {
725 call->conn->transport.report_output_data(call->conn);
729 return NT_STATUS_OK;
732 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
733 uint32_t fault_code)
736 * We add the call to the pending_call_list
737 * in order to defer the termination.
739 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
741 return dcesrv_fault_with_flags(call, fault_code,
742 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
745 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
747 DLIST_REMOVE(c->conn->contexts, c);
749 if (c->iface && c->iface->unbind) {
750 c->iface->unbind(c, c->iface);
751 c->iface = NULL;
754 return 0;
757 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
759 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
760 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
761 enum dcerpc_transport_t transport =
762 dcerpc_binding_get_transport(endpoint->ep_description);
763 struct dcesrv_connection_context *context = dce_call->context;
764 const struct dcesrv_interface *iface = context->iface;
766 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
768 if (transport == NCALRPC) {
769 context->allow_connect = true;
770 return;
774 * allow overwrite per interface
775 * allow dcerpc auth level connect:<interface>
777 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
778 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
779 "allow dcerpc auth level connect",
780 iface->name,
781 context->allow_connect);
784 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
785 const struct dcesrv_interface *iface)
787 if (dce_call->context == NULL) {
788 return NT_STATUS_INTERNAL_ERROR;
792 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
793 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
795 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
796 return NT_STATUS_OK;
799 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
800 const struct dcesrv_interface *iface)
802 if (dce_call->context == NULL) {
803 return NT_STATUS_INTERNAL_ERROR;
806 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
807 return NT_STATUS_OK;
810 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
811 const struct dcesrv_interface *iface)
813 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
814 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
815 enum dcerpc_transport_t transport =
816 dcerpc_binding_get_transport(endpoint->ep_description);
817 struct dcesrv_connection_context *context = dce_call->context;
819 if (context == NULL) {
820 return NT_STATUS_INTERNAL_ERROR;
823 if (transport == NCALRPC) {
824 context->allow_connect = true;
825 return NT_STATUS_OK;
829 * allow overwrite per interface
830 * allow dcerpc auth level connect:<interface>
832 context->allow_connect = false;
833 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
834 "allow dcerpc auth level connect",
835 iface->name,
836 context->allow_connect);
837 return NT_STATUS_OK;
840 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
841 const struct dcesrv_interface *iface)
843 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
844 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
845 enum dcerpc_transport_t transport =
846 dcerpc_binding_get_transport(endpoint->ep_description);
847 struct dcesrv_connection_context *context = dce_call->context;
849 if (context == NULL) {
850 return NT_STATUS_INTERNAL_ERROR;
853 if (transport == NCALRPC) {
854 context->allow_connect = true;
855 return NT_STATUS_OK;
859 * allow overwrite per interface
860 * allow dcerpc auth level connect:<interface>
862 context->allow_connect = true;
863 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
864 "allow dcerpc auth level connect",
865 iface->name,
866 context->allow_connect);
867 return NT_STATUS_OK;
870 struct dcesrv_conn_auth_wait_context {
871 struct tevent_req *req;
872 bool done;
873 NTSTATUS status;
876 struct dcesrv_conn_auth_wait_state {
877 uint8_t dummy;
880 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
881 struct tevent_context *ev,
882 void *private_data)
884 struct dcesrv_conn_auth_wait_context *auth_wait =
885 talloc_get_type_abort(private_data,
886 struct dcesrv_conn_auth_wait_context);
887 struct tevent_req *req = NULL;
888 struct dcesrv_conn_auth_wait_state *state = NULL;
890 req = tevent_req_create(mem_ctx, &state,
891 struct dcesrv_conn_auth_wait_state);
892 if (req == NULL) {
893 return NULL;
895 auth_wait->req = req;
897 tevent_req_defer_callback(req, ev);
899 if (!auth_wait->done) {
900 return req;
903 if (tevent_req_nterror(req, auth_wait->status)) {
904 return tevent_req_post(req, ev);
907 tevent_req_done(req);
908 return tevent_req_post(req, ev);
911 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
913 return tevent_req_simple_recv_ntstatus(req);
916 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
918 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
920 if (conn->wait_send != NULL) {
921 return NT_STATUS_INTERNAL_ERROR;
924 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
925 if (auth_wait == NULL) {
926 return NT_STATUS_NO_MEMORY;
929 conn->wait_private = auth_wait;
930 conn->wait_send = dcesrv_conn_auth_wait_send;
931 conn->wait_recv = dcesrv_conn_auth_wait_recv;
932 return NT_STATUS_OK;
935 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
936 NTSTATUS status)
938 struct dcesrv_conn_auth_wait_context *auth_wait =
939 talloc_get_type_abort(conn->wait_private,
940 struct dcesrv_conn_auth_wait_context);
942 auth_wait->done = true;
943 auth_wait->status = status;
945 if (auth_wait->req == NULL) {
946 return;
949 if (tevent_req_nterror(auth_wait->req, status)) {
950 return;
953 tevent_req_done(auth_wait->req);
956 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
958 static void dcesrv_bind_done(struct tevent_req *subreq);
961 handle a bind request
963 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
965 struct dcesrv_connection *conn = call->conn;
966 struct ncacn_packet *pkt = &call->ack_pkt;
967 NTSTATUS status;
968 uint32_t extra_flags = 0;
969 uint16_t max_req = 0;
970 uint16_t max_rep = 0;
971 const char *ep_prefix = "";
972 const char *endpoint = NULL;
973 struct dcesrv_auth *auth = call->auth_state;
974 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
975 struct dcerpc_ack_ctx *ack_features = NULL;
976 struct tevent_req *subreq = NULL;
977 size_t i;
979 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
980 DCERPC_PKT_BIND,
981 call->pkt.u.bind.auth_info.length,
982 0, /* required flags */
983 DCERPC_PFC_FLAG_FIRST |
984 DCERPC_PFC_FLAG_LAST |
985 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
986 0x08 | /* this is not defined, but should be ignored */
987 DCERPC_PFC_FLAG_CONC_MPX |
988 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
989 DCERPC_PFC_FLAG_MAYBE |
990 DCERPC_PFC_FLAG_OBJECT_UUID);
991 if (!NT_STATUS_IS_OK(status)) {
992 return dcesrv_bind_nak(call,
993 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
996 /* max_recv_frag and max_xmit_frag result always in the same value! */
997 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
998 call->pkt.u.bind.max_recv_frag);
1000 * The values are between 2048 and 5840 tested against Windows 2012R2
1001 * via ncacn_ip_tcp on port 135.
1003 max_req = MAX(2048, max_req);
1004 max_rep = MIN(max_req, call->conn->max_recv_frag);
1005 /* They are truncated to an 8 byte boundary. */
1006 max_rep &= 0xFFF8;
1008 /* max_recv_frag and max_xmit_frag result always in the same value! */
1009 call->conn->max_recv_frag = max_rep;
1010 call->conn->max_xmit_frag = max_rep;
1013 if provided, check the assoc_group is valid
1015 if (call->pkt.u.bind.assoc_group_id != 0) {
1016 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
1017 call->conn->dce_ctx,
1018 call->pkt.u.bind.assoc_group_id);
1019 } else {
1020 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
1021 call->conn->dce_ctx);
1025 * The NETLOGON server does not use handles and so
1026 * there is no need to support association groups, but
1027 * we need to give back a number regardless.
1029 * We have to do this when it is not run as a single process,
1030 * because then it can't see the other valid association
1031 * groups. We handle this genericly for all endpoints not
1032 * running in single process mode.
1034 * We know which endpoint we are on even before checking the
1035 * iface UUID, so for simplicity we enforce the same policy
1036 * for all interfaces on the endpoint.
1038 * This means that where NETLOGON
1039 * shares an endpoint (such as ncalrpc or of 'lsa over
1040 * netlogon' is set) we will still check association groups.
1044 if (call->conn->assoc_group == NULL &&
1045 !call->conn->endpoint->use_single_process) {
1046 call->conn->assoc_group
1047 = dcesrv_assoc_group_new(call->conn,
1048 call->conn->dce_ctx);
1050 if (call->conn->assoc_group == NULL) {
1051 return dcesrv_bind_nak(call, 0);
1054 if (call->pkt.u.bind.num_contexts < 1) {
1055 return dcesrv_bind_nak(call, 0);
1058 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1059 call->pkt.u.bind.num_contexts);
1060 if (ack_ctx_list == NULL) {
1061 return dcesrv_bind_nak(call, 0);
1065 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1066 * dcesrv_check_or_create_context()) and do some protocol validation
1067 * and set sane defaults.
1069 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1070 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1071 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1072 bool is_feature = false;
1073 uint64_t features = 0;
1075 if (c->num_transfer_syntaxes == 0) {
1076 return dcesrv_bind_nak(call, 0);
1079 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1080 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1083 * It's only treated as bind time feature request, if the first
1084 * transfer_syntax matches, all others are ignored.
1086 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1087 &features);
1088 if (!is_feature) {
1089 continue;
1092 if (ack_features != NULL) {
1094 * Only one bind time feature context is allowed.
1096 return dcesrv_bind_nak(call, 0);
1098 ack_features = a;
1100 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1101 a->reason.negotiate = 0;
1102 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1103 /* not supported yet */
1105 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1106 a->reason.negotiate |=
1107 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1110 call->conn->bind_time_features = a->reason.negotiate;
1114 * Try to negotiate one new presentation context.
1116 * Deep in here we locate the iface (by uuid) that the client
1117 * requested, from the list of interfaces on the
1118 * call->conn->endpoint, and call iface->bind() on that iface.
1120 * call->conn was set up at the accept() of the socket, and
1121 * call->conn->endpoint has a list of interfaces restricted to
1122 * this port or pipe.
1124 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1125 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1126 return dcesrv_bind_nak(call, 0);
1128 if (!NT_STATUS_IS_OK(status)) {
1129 return status;
1133 * At this point we still don't know which interface (eg
1134 * netlogon, lsa, drsuapi) the caller requested in this bind!
1135 * The most recently added context is available as the first
1136 * element in the linked list at call->conn->contexts, that is
1137 * call->conn->contexts->iface, but they may not have
1138 * requested one at all!
1141 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1142 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1143 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1144 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1147 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1148 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1152 * After finding the interface and setting up the NDR
1153 * transport negotiation etc, handle any authentication that
1154 * is being requested.
1156 if (!dcesrv_auth_bind(call)) {
1158 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1160 * With DCERPC_AUTH_LEVEL_NONE, we get the
1161 * reject_reason in auth->auth_context_id.
1163 return dcesrv_bind_nak(call, auth->auth_context_id);
1167 * This must a be a temporary failure e.g. talloc or invalid
1168 * configuration, e.g. no machine account.
1170 return dcesrv_bind_nak(call,
1171 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1174 /* setup a bind_ack */
1175 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1176 pkt->auth_length = 0;
1177 pkt->call_id = call->pkt.call_id;
1178 pkt->ptype = DCERPC_PKT_BIND_ACK;
1179 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1180 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1181 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1182 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1184 endpoint = dcerpc_binding_get_string_option(
1185 call->conn->endpoint->ep_description,
1186 "endpoint");
1187 if (endpoint == NULL) {
1188 endpoint = "";
1191 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1193 * TODO: check if this is really needed
1195 * Or if we should fix this in our idl files.
1197 ep_prefix = "\\PIPE\\";
1198 endpoint += 6;
1201 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1202 ep_prefix,
1203 endpoint);
1204 if (pkt->u.bind_ack.secondary_address == NULL) {
1205 return NT_STATUS_NO_MEMORY;
1207 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1208 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1209 pkt->u.bind_ack.auth_info = data_blob_null;
1211 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 return dcesrv_bind_nak(call, 0);
1216 if (auth->auth_finished) {
1217 return dcesrv_auth_reply(call);
1220 subreq = gensec_update_send(call, call->event_ctx,
1221 auth->gensec_security,
1222 call->in_auth_info.credentials);
1223 if (subreq == NULL) {
1224 return NT_STATUS_NO_MEMORY;
1226 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1228 return dcesrv_conn_auth_wait_setup(conn);
1231 static void dcesrv_bind_done(struct tevent_req *subreq)
1233 struct dcesrv_call_state *call =
1234 tevent_req_callback_data(subreq,
1235 struct dcesrv_call_state);
1236 struct dcesrv_connection *conn = call->conn;
1237 NTSTATUS status;
1239 status = gensec_update_recv(subreq, call,
1240 &call->out_auth_info->credentials);
1241 TALLOC_FREE(subreq);
1243 status = dcesrv_auth_complete(call, status);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 status = dcesrv_bind_nak(call, 0);
1246 dcesrv_conn_auth_wait_finished(conn, status);
1247 return;
1250 status = dcesrv_auth_reply(call);
1251 dcesrv_conn_auth_wait_finished(conn, status);
1252 return;
1255 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1257 struct ncacn_packet *pkt = &call->ack_pkt;
1258 struct data_blob_list_item *rep = NULL;
1259 NTSTATUS status;
1261 rep = talloc_zero(call, struct data_blob_list_item);
1262 if (!rep) {
1263 return NT_STATUS_NO_MEMORY;
1266 status = ncacn_push_auth(&rep->blob, call, pkt,
1267 call->out_auth_info);
1268 if (!NT_STATUS_IS_OK(status)) {
1269 return status;
1272 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1274 DLIST_ADD_END(call->replies, rep);
1275 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1277 if (call->conn->call_list && call->conn->call_list->replies) {
1278 if (call->conn->transport.report_output_data) {
1279 call->conn->transport.report_output_data(call->conn);
1283 return NT_STATUS_OK;
1287 static void dcesrv_auth3_done(struct tevent_req *subreq);
1290 handle a auth3 request
1292 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1294 struct dcesrv_connection *conn = call->conn;
1295 struct dcesrv_auth *auth = call->auth_state;
1296 struct tevent_req *subreq = NULL;
1297 NTSTATUS status;
1299 if (!auth->auth_started) {
1300 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1303 if (auth->auth_finished) {
1304 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1307 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1308 DCERPC_PKT_AUTH3,
1309 call->pkt.u.auth3.auth_info.length,
1310 0, /* required flags */
1311 DCERPC_PFC_FLAG_FIRST |
1312 DCERPC_PFC_FLAG_LAST |
1313 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1314 0x08 | /* this is not defined, but should be ignored */
1315 DCERPC_PFC_FLAG_CONC_MPX |
1316 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1317 DCERPC_PFC_FLAG_MAYBE |
1318 DCERPC_PFC_FLAG_OBJECT_UUID);
1319 if (!NT_STATUS_IS_OK(status)) {
1320 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1323 /* handle the auth3 in the auth code */
1324 if (!dcesrv_auth_prepare_auth3(call)) {
1326 * we don't send a reply to a auth3 request,
1327 * except by a fault.
1329 * In anycase we mark the connection as
1330 * invalid.
1332 auth->auth_invalid = true;
1333 if (call->fault_code != 0) {
1334 return dcesrv_fault_disconnect(call, call->fault_code);
1336 TALLOC_FREE(call);
1337 return NT_STATUS_OK;
1340 subreq = gensec_update_send(call, call->event_ctx,
1341 auth->gensec_security,
1342 call->in_auth_info.credentials);
1343 if (subreq == NULL) {
1344 return NT_STATUS_NO_MEMORY;
1346 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1348 return dcesrv_conn_auth_wait_setup(conn);
1351 static void dcesrv_auth3_done(struct tevent_req *subreq)
1353 struct dcesrv_call_state *call =
1354 tevent_req_callback_data(subreq,
1355 struct dcesrv_call_state);
1356 struct dcesrv_connection *conn = call->conn;
1357 struct dcesrv_auth *auth = call->auth_state;
1358 NTSTATUS status;
1360 status = gensec_update_recv(subreq, call,
1361 &call->out_auth_info->credentials);
1362 TALLOC_FREE(subreq);
1364 status = dcesrv_auth_complete(call, status);
1365 if (!NT_STATUS_IS_OK(status)) {
1367 * we don't send a reply to a auth3 request,
1368 * except by a fault.
1370 * In anycase we mark the connection as
1371 * invalid.
1373 auth->auth_invalid = true;
1374 if (call->fault_code != 0) {
1375 status = dcesrv_fault_disconnect(call, call->fault_code);
1376 dcesrv_conn_auth_wait_finished(conn, status);
1377 return;
1379 TALLOC_FREE(call);
1380 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1381 return;
1385 * we don't send a reply to a auth3 request.
1387 TALLOC_FREE(call);
1388 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1389 return;
1393 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1394 const struct dcerpc_bind *b,
1395 const struct dcerpc_ctx_list *ctx,
1396 struct dcerpc_ack_ctx *ack,
1397 bool validate_only,
1398 const struct ndr_syntax_id *supported_transfer)
1400 uint32_t if_version;
1401 struct dcesrv_connection_context *context;
1402 const struct dcesrv_interface *iface;
1403 struct GUID uuid;
1404 NTSTATUS status;
1405 const struct ndr_syntax_id *selected_transfer = NULL;
1406 size_t i;
1407 bool ok;
1409 if (b == NULL) {
1410 return NT_STATUS_INTERNAL_ERROR;
1412 if (ctx == NULL) {
1413 return NT_STATUS_INTERNAL_ERROR;
1415 if (ctx->num_transfer_syntaxes < 1) {
1416 return NT_STATUS_INTERNAL_ERROR;
1418 if (ack == NULL) {
1419 return NT_STATUS_INTERNAL_ERROR;
1421 if (supported_transfer == NULL) {
1422 return NT_STATUS_INTERNAL_ERROR;
1425 switch (ack->result) {
1426 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1427 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1429 * We is already completed.
1431 return NT_STATUS_OK;
1432 default:
1433 break;
1436 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1437 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1439 if_version = ctx->abstract_syntax.if_version;
1440 uuid = ctx->abstract_syntax.uuid;
1442 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1443 if (iface == NULL) {
1444 char *uuid_str = GUID_string(call, &uuid);
1445 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1446 talloc_free(uuid_str);
1448 * We report this only via ack->result
1450 return NT_STATUS_OK;
1453 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1454 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1456 if (validate_only) {
1458 * We report this only via ack->result
1460 return NT_STATUS_OK;
1463 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1465 * we only do NDR encoded dcerpc for now.
1467 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1468 supported_transfer);
1469 if (ok) {
1470 selected_transfer = supported_transfer;
1471 break;
1475 context = dcesrv_find_context(call->conn, ctx->context_id);
1476 if (context != NULL) {
1477 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1478 &ctx->abstract_syntax);
1479 if (!ok) {
1480 return NT_STATUS_RPC_PROTOCOL_ERROR;
1483 if (selected_transfer != NULL) {
1484 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1485 selected_transfer);
1486 if (!ok) {
1487 return NT_STATUS_RPC_PROTOCOL_ERROR;
1490 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1491 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1492 ack->syntax = context->transfer_syntax;
1496 * We report this only via ack->result
1498 return NT_STATUS_OK;
1501 if (selected_transfer == NULL) {
1503 * We report this only via ack->result
1505 return NT_STATUS_OK;
1508 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1509 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1511 /* add this context to the list of available context_ids */
1512 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1513 if (context == NULL) {
1514 return NT_STATUS_NO_MEMORY;
1516 context->conn = call->conn;
1517 context->context_id = ctx->context_id;
1518 context->iface = iface;
1519 context->transfer_syntax = *selected_transfer;
1520 context->private_data = NULL;
1521 DLIST_ADD(call->conn->contexts, context);
1522 call->context = context;
1523 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1525 dcesrv_prepare_context_auth(call);
1528 * Multiplex is supported by default
1530 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1532 status = iface->bind(call, iface, if_version);
1533 call->context = NULL;
1534 if (!NT_STATUS_IS_OK(status)) {
1535 /* we don't want to trigger the iface->unbind() hook */
1536 context->iface = NULL;
1537 talloc_free(context);
1539 * We report this only via ack->result
1541 return NT_STATUS_OK;
1544 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1545 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1546 ack->syntax = context->transfer_syntax;
1547 return NT_STATUS_OK;
1550 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1551 const struct dcerpc_bind *b,
1552 struct dcerpc_ack_ctx *ack_ctx_list)
1554 NTSTATUS status;
1555 size_t i;
1556 bool validate_only = false;
1557 bool preferred_ndr32;
1560 * Try to negotiate one new presentation context,
1561 * using our preferred transfer syntax.
1563 for (i = 0; i < b->num_contexts; i++) {
1564 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1565 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1567 status = dcesrv_check_or_create_context(call, b, c, a,
1568 validate_only,
1569 call->conn->preferred_transfer);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 return status;
1574 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1576 * We managed to negotiate one context.
1578 * => we're done.
1580 validate_only = true;
1584 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1585 call->conn->preferred_transfer);
1586 if (preferred_ndr32) {
1588 * We're done.
1590 return NT_STATUS_OK;
1594 * Try to negotiate one new presentation context,
1595 * using NDR 32 as fallback.
1597 for (i = 0; i < b->num_contexts; i++) {
1598 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1599 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1601 status = dcesrv_check_or_create_context(call, b, c, a,
1602 validate_only,
1603 &ndr_transfer_syntax_ndr);
1604 if (!NT_STATUS_IS_OK(status)) {
1605 return status;
1608 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1610 * We managed to negotiate one context.
1612 * => we're done.
1614 validate_only = true;
1618 return NT_STATUS_OK;
1621 static void dcesrv_alter_done(struct tevent_req *subreq);
1624 handle a alter context request
1626 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1628 struct dcesrv_connection *conn = call->conn;
1629 NTSTATUS status;
1630 bool auth_ok = false;
1631 struct ncacn_packet *pkt = &call->ack_pkt;
1632 uint32_t extra_flags = 0;
1633 struct dcesrv_auth *auth = call->auth_state;
1634 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1635 struct tevent_req *subreq = NULL;
1636 size_t i;
1638 if (!call->conn->allow_alter) {
1639 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1642 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1643 DCERPC_PKT_ALTER,
1644 call->pkt.u.alter.auth_info.length,
1645 0, /* required flags */
1646 DCERPC_PFC_FLAG_FIRST |
1647 DCERPC_PFC_FLAG_LAST |
1648 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1649 0x08 | /* this is not defined, but should be ignored */
1650 DCERPC_PFC_FLAG_CONC_MPX |
1651 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1652 DCERPC_PFC_FLAG_MAYBE |
1653 DCERPC_PFC_FLAG_OBJECT_UUID);
1654 if (!NT_STATUS_IS_OK(status)) {
1655 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1658 auth_ok = dcesrv_auth_alter(call);
1659 if (!auth_ok) {
1660 if (call->fault_code != 0) {
1661 return dcesrv_fault_disconnect(call, call->fault_code);
1665 if (call->pkt.u.alter.num_contexts < 1) {
1666 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1669 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1670 call->pkt.u.alter.num_contexts);
1671 if (ack_ctx_list == NULL) {
1672 return NT_STATUS_NO_MEMORY;
1676 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1677 * dcesrv_check_or_create_context()) and do some protocol validation
1678 * and set sane defaults.
1680 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1681 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1682 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1684 if (c->num_transfer_syntaxes == 0) {
1685 return dcesrv_fault_disconnect(call,
1686 DCERPC_NCA_S_PROTO_ERROR);
1689 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1690 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1694 * Try to negotiate one new presentation context.
1696 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1697 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1698 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1700 if (!NT_STATUS_IS_OK(status)) {
1701 return status;
1704 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1705 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1706 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1707 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1710 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1711 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1714 /* handle any authentication that is being requested */
1715 if (!auth_ok) {
1716 if (call->in_auth_info.auth_type != auth->auth_type) {
1717 return dcesrv_fault_disconnect(call,
1718 DCERPC_FAULT_SEC_PKG_ERROR);
1720 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1723 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1724 pkt->auth_length = 0;
1725 pkt->call_id = call->pkt.call_id;
1726 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1727 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1728 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1729 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1730 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1731 pkt->u.alter_resp.secondary_address = "";
1732 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1733 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1734 pkt->u.alter_resp.auth_info = data_blob_null;
1736 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1737 if (!NT_STATUS_IS_OK(status)) {
1738 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1741 if (auth->auth_finished) {
1742 return dcesrv_auth_reply(call);
1745 subreq = gensec_update_send(call, call->event_ctx,
1746 auth->gensec_security,
1747 call->in_auth_info.credentials);
1748 if (subreq == NULL) {
1749 return NT_STATUS_NO_MEMORY;
1751 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1753 return dcesrv_conn_auth_wait_setup(conn);
1756 static void dcesrv_alter_done(struct tevent_req *subreq)
1758 struct dcesrv_call_state *call =
1759 tevent_req_callback_data(subreq,
1760 struct dcesrv_call_state);
1761 struct dcesrv_connection *conn = call->conn;
1762 NTSTATUS status;
1764 status = gensec_update_recv(subreq, call,
1765 &call->out_auth_info->credentials);
1766 TALLOC_FREE(subreq);
1768 status = dcesrv_auth_complete(call, status);
1769 if (!NT_STATUS_IS_OK(status)) {
1770 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1771 dcesrv_conn_auth_wait_finished(conn, status);
1772 return;
1775 status = dcesrv_auth_reply(call);
1776 dcesrv_conn_auth_wait_finished(conn, status);
1777 return;
1781 possibly save the call for inspection with ndrdump
1783 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1785 #ifdef DEVELOPER
1786 char *fname;
1787 const char *dump_dir;
1788 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1789 if (!dump_dir) {
1790 return;
1792 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1793 dump_dir,
1794 call->context->iface->name,
1795 call->pkt.u.request.opnum,
1796 why);
1797 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1798 DEBUG(0,("RPC SAVED %s\n", fname));
1800 talloc_free(fname);
1801 #endif
1804 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1806 TALLOC_CTX *frame = talloc_stackframe();
1807 const struct dcesrv_auth *auth = call->auth_state;
1808 const uint32_t bitmask1 = auth->client_hdr_signing ?
1809 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1810 const struct dcerpc_sec_vt_pcontext pcontext = {
1811 .abstract_syntax = call->context->iface->syntax_id,
1812 .transfer_syntax = call->context->transfer_syntax,
1814 const struct dcerpc_sec_vt_header2 header2 =
1815 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1816 enum ndr_err_code ndr_err;
1817 struct dcerpc_sec_verification_trailer *vt = NULL;
1818 NTSTATUS status = NT_STATUS_OK;
1819 bool ok;
1821 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1823 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1824 frame, &vt);
1825 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1826 status = ndr_map_error2ntstatus(ndr_err);
1827 goto done;
1830 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1831 &pcontext, &header2);
1832 if (!ok) {
1833 status = NT_STATUS_ACCESS_DENIED;
1834 goto done;
1836 done:
1837 TALLOC_FREE(frame);
1838 return status;
1842 handle a dcerpc request packet
1844 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1846 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1847 struct dcesrv_auth *auth = call->auth_state;
1848 enum dcerpc_transport_t transport =
1849 dcerpc_binding_get_transport(endpoint->ep_description);
1850 struct ndr_pull *pull;
1851 NTSTATUS status;
1853 if (!auth->auth_finished) {
1854 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1857 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1858 if (auth->gensec_security != NULL &&
1859 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1860 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1863 if (call->context == NULL) {
1864 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1865 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1868 switch (auth->auth_level) {
1869 case DCERPC_AUTH_LEVEL_NONE:
1870 case DCERPC_AUTH_LEVEL_PACKET:
1871 case DCERPC_AUTH_LEVEL_INTEGRITY:
1872 case DCERPC_AUTH_LEVEL_PRIVACY:
1873 break;
1874 default:
1875 if (!call->context->allow_connect) {
1876 char *addr;
1878 addr = tsocket_address_string(call->conn->remote_address,
1879 call);
1881 DEBUG(2, ("%s: restrict auth_level_connect access "
1882 "to [%s] with auth[type=0x%x,level=0x%x] "
1883 "on [%s] from [%s]\n",
1884 __func__, call->context->iface->name,
1885 auth->auth_type,
1886 auth->auth_level,
1887 derpc_transport_string_by_transport(transport),
1888 addr));
1889 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1891 break;
1894 if (auth->auth_level < call->context->min_auth_level) {
1895 char *addr;
1897 addr = tsocket_address_string(call->conn->remote_address, call);
1899 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1900 "to [%s] with auth[type=0x%x,level=0x%x] "
1901 "on [%s] from [%s]\n",
1902 __func__,
1903 call->context->min_auth_level,
1904 call->context->iface->name,
1905 auth->auth_type,
1906 auth->auth_level,
1907 derpc_transport_string_by_transport(transport),
1908 addr));
1909 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1912 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1913 NT_STATUS_HAVE_NO_MEMORY(pull);
1915 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1917 call->ndr_pull = pull;
1919 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1920 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1923 status = dcesrv_check_verification_trailer(call);
1924 if (!NT_STATUS_IS_OK(status)) {
1925 uint32_t faultcode = DCERPC_FAULT_OTHER;
1926 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1927 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1929 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1930 nt_errstr(status)));
1931 return dcesrv_fault(call, faultcode);
1934 /* unravel the NDR for the packet */
1935 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1936 if (!NT_STATUS_IS_OK(status)) {
1937 uint8_t extra_flags = 0;
1938 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1939 /* we got an unknown call */
1940 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1941 call->pkt.u.request.opnum,
1942 call->context->iface->name));
1943 dcesrv_save_call(call, "unknown");
1944 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1945 } else {
1946 dcesrv_save_call(call, "pullfail");
1948 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1951 if (pull->offset != pull->data_size) {
1952 dcesrv_save_call(call, "extrabytes");
1953 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1954 pull->data_size - pull->offset));
1957 /* call the dispatch function */
1958 status = call->context->iface->dispatch(call, call, call->r);
1959 if (!NT_STATUS_IS_OK(status)) {
1960 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1961 call->context->iface->name,
1962 call->pkt.u.request.opnum,
1963 dcerpc_errstr(pull, call->fault_code)));
1964 return dcesrv_fault(call, call->fault_code);
1967 /* add the call to the pending list */
1968 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1970 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1971 return NT_STATUS_OK;
1974 return dcesrv_reply(call);
1979 remove the call from the right list when freed
1981 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1983 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1984 return 0;
1987 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1989 return conn->local_address;
1992 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1994 return conn->remote_address;
1998 process some input to a dcerpc endpoint server.
2000 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2001 struct ncacn_packet *pkt,
2002 DATA_BLOB blob)
2004 NTSTATUS status;
2005 struct dcesrv_call_state *call;
2006 struct dcesrv_call_state *existing = NULL;
2008 call = talloc_zero(dce_conn, struct dcesrv_call_state);
2009 if (!call) {
2010 data_blob_free(&blob);
2011 talloc_free(pkt);
2012 return NT_STATUS_NO_MEMORY;
2014 call->conn = dce_conn;
2015 call->event_ctx = dce_conn->event_ctx;
2016 call->msg_ctx = dce_conn->msg_ctx;
2017 call->state_flags = call->conn->state_flags;
2018 call->time = timeval_current();
2019 call->list = DCESRV_LIST_NONE;
2021 talloc_steal(call, pkt);
2022 talloc_steal(call, blob.data);
2023 call->pkt = *pkt;
2025 call->auth_state = dce_conn->default_auth_state;
2027 talloc_set_destructor(call, dcesrv_call_dequeue);
2029 if (call->conn->allow_bind) {
2031 * Only one bind is possible per connection
2033 call->conn->allow_bind = false;
2034 return dcesrv_bind(call);
2037 /* we have to check the signing here, before combining the
2038 pdus */
2039 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2040 if (!call->auth_state->auth_finished) {
2041 return dcesrv_fault_disconnect(call,
2042 DCERPC_NCA_S_PROTO_ERROR);
2045 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2046 DCERPC_PKT_REQUEST,
2047 call->pkt.u.request.stub_and_verifier.length,
2048 0, /* required_flags */
2049 DCERPC_PFC_FLAG_FIRST |
2050 DCERPC_PFC_FLAG_LAST |
2051 DCERPC_PFC_FLAG_PENDING_CANCEL |
2052 0x08 | /* this is not defined, but should be ignored */
2053 DCERPC_PFC_FLAG_CONC_MPX |
2054 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2055 DCERPC_PFC_FLAG_MAYBE |
2056 DCERPC_PFC_FLAG_OBJECT_UUID);
2057 if (!NT_STATUS_IS_OK(status)) {
2058 return dcesrv_fault_disconnect(call,
2059 DCERPC_NCA_S_PROTO_ERROR);
2062 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2064 * We don't use dcesrv_fault_disconnect()
2065 * here, because we don't want to set
2066 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2068 * Note that we don't check against the negotiated
2069 * max_recv_frag, but a hard coded value.
2071 dcesrv_call_disconnect_after(call,
2072 "dcesrv_auth_request - frag_length too large");
2073 return dcesrv_fault(call,
2074 DCERPC_NCA_S_PROTO_ERROR);
2077 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2078 if (dce_conn->pending_call_list != NULL) {
2080 * concurrent requests are only allowed
2081 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2083 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2084 dcesrv_call_disconnect_after(call,
2085 "dcesrv_auth_request - "
2086 "existing pending call without CONN_MPX");
2087 return dcesrv_fault(call,
2088 DCERPC_NCA_S_PROTO_ERROR);
2091 /* only one request is possible in the fragmented list */
2092 if (dce_conn->incoming_fragmented_call_list != NULL) {
2093 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2095 * Without DCERPC_PFC_FLAG_CONC_MPX
2096 * we need to return the FAULT on the
2097 * already existing call.
2099 * This is important to get the
2100 * call_id and context_id right.
2102 TALLOC_FREE(call);
2103 call = dce_conn->incoming_fragmented_call_list;
2105 dcesrv_call_disconnect_after(call,
2106 "dcesrv_auth_request - "
2107 "existing fragmented call");
2108 return dcesrv_fault(call,
2109 DCERPC_NCA_S_PROTO_ERROR);
2111 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2112 return dcesrv_fault_disconnect(call,
2113 DCERPC_FAULT_NO_CALL_ACTIVE);
2115 call->context = dcesrv_find_context(call->conn,
2116 call->pkt.u.request.context_id);
2117 if (call->context == NULL) {
2118 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2119 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2121 } else {
2122 const struct dcerpc_request *nr = &call->pkt.u.request;
2123 const struct dcerpc_request *er = NULL;
2124 int cmp;
2126 existing = dcesrv_find_fragmented_call(dce_conn,
2127 call->pkt.call_id);
2128 if (existing == NULL) {
2129 dcesrv_call_disconnect_after(call,
2130 "dcesrv_auth_request - "
2131 "no existing fragmented call");
2132 return dcesrv_fault(call,
2133 DCERPC_NCA_S_PROTO_ERROR);
2135 er = &existing->pkt.u.request;
2137 if (call->pkt.ptype != existing->pkt.ptype) {
2138 /* trying to play silly buggers are we? */
2139 return dcesrv_fault_disconnect(existing,
2140 DCERPC_NCA_S_PROTO_ERROR);
2142 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2143 sizeof(pkt->drep));
2144 if (cmp != 0) {
2145 return dcesrv_fault_disconnect(existing,
2146 DCERPC_NCA_S_PROTO_ERROR);
2148 if (nr->context_id != er->context_id) {
2149 return dcesrv_fault_disconnect(existing,
2150 DCERPC_NCA_S_PROTO_ERROR);
2152 if (nr->opnum != er->opnum) {
2153 return dcesrv_fault_disconnect(existing,
2154 DCERPC_NCA_S_PROTO_ERROR);
2159 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2160 bool ok;
2161 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2163 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2164 payload_offset += 16;
2167 ok = dcesrv_auth_pkt_pull(call, &blob,
2168 0, /* required_flags */
2169 DCERPC_PFC_FLAG_FIRST |
2170 DCERPC_PFC_FLAG_LAST |
2171 DCERPC_PFC_FLAG_PENDING_CANCEL |
2172 0x08 | /* this is not defined, but should be ignored */
2173 DCERPC_PFC_FLAG_CONC_MPX |
2174 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2175 DCERPC_PFC_FLAG_MAYBE |
2176 DCERPC_PFC_FLAG_OBJECT_UUID,
2177 payload_offset,
2178 &call->pkt.u.request.stub_and_verifier);
2179 if (!ok) {
2181 * We don't use dcesrv_fault_disconnect()
2182 * here, because we don't want to set
2183 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2185 dcesrv_call_disconnect_after(call,
2186 "dcesrv_auth_request - failed");
2187 if (call->fault_code == 0) {
2188 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2190 return dcesrv_fault(call, call->fault_code);
2194 /* see if this is a continued packet */
2195 if (existing != NULL) {
2196 struct dcerpc_request *er = &existing->pkt.u.request;
2197 const struct dcerpc_request *nr = &call->pkt.u.request;
2198 size_t available;
2199 size_t alloc_size;
2200 size_t alloc_hint;
2203 * Up to 4 MByte are allowed by all fragments
2205 available = dce_conn->max_total_request_size;
2206 if (er->stub_and_verifier.length > available) {
2207 dcesrv_call_disconnect_after(existing,
2208 "dcesrv_auth_request - existing payload too large");
2209 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2211 available -= er->stub_and_verifier.length;
2212 if (nr->alloc_hint > available) {
2213 dcesrv_call_disconnect_after(existing,
2214 "dcesrv_auth_request - alloc hint too large");
2215 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2217 if (nr->stub_and_verifier.length > available) {
2218 dcesrv_call_disconnect_after(existing,
2219 "dcesrv_auth_request - new payload too large");
2220 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2222 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2223 /* allocate at least 1 byte */
2224 alloc_hint = MAX(alloc_hint, 1);
2225 alloc_size = er->stub_and_verifier.length +
2226 nr->stub_and_verifier.length;
2227 alloc_size = MAX(alloc_size, alloc_hint);
2229 er->stub_and_verifier.data =
2230 talloc_realloc(existing,
2231 er->stub_and_verifier.data,
2232 uint8_t, alloc_size);
2233 if (er->stub_and_verifier.data == NULL) {
2234 TALLOC_FREE(call);
2235 return dcesrv_fault_with_flags(existing,
2236 DCERPC_FAULT_OUT_OF_RESOURCES,
2237 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2239 memcpy(er->stub_and_verifier.data +
2240 er->stub_and_verifier.length,
2241 nr->stub_and_verifier.data,
2242 nr->stub_and_verifier.length);
2243 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2245 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2247 TALLOC_FREE(call);
2248 call = existing;
2251 /* this may not be the last pdu in the chain - if its isn't then
2252 just put it on the incoming_fragmented_call_list and wait for the rest */
2253 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2254 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2256 * Up to 4 MByte are allowed by all fragments
2258 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2259 dcesrv_call_disconnect_after(call,
2260 "dcesrv_auth_request - initial alloc hint too large");
2261 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2263 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2264 return NT_STATUS_OK;
2267 /* This removes any fragments we may have had stashed away */
2268 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2270 switch (call->pkt.ptype) {
2271 case DCERPC_PKT_BIND:
2272 status = dcesrv_bind_nak(call,
2273 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2274 break;
2275 case DCERPC_PKT_AUTH3:
2276 status = dcesrv_auth3(call);
2277 break;
2278 case DCERPC_PKT_ALTER:
2279 status = dcesrv_alter(call);
2280 break;
2281 case DCERPC_PKT_REQUEST:
2282 status = dcesrv_request(call);
2283 break;
2284 case DCERPC_PKT_CO_CANCEL:
2285 case DCERPC_PKT_ORPHANED:
2287 * Window just ignores CO_CANCEL and ORPHANED,
2288 * so we do...
2290 status = NT_STATUS_OK;
2291 TALLOC_FREE(call);
2292 break;
2293 case DCERPC_PKT_BIND_ACK:
2294 case DCERPC_PKT_BIND_NAK:
2295 case DCERPC_PKT_ALTER_RESP:
2296 case DCERPC_PKT_RESPONSE:
2297 case DCERPC_PKT_FAULT:
2298 case DCERPC_PKT_SHUTDOWN:
2299 default:
2300 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2301 break;
2304 /* if we are going to be sending a reply then add
2305 it to the list of pending calls. We add it to the end to keep the call
2306 list in the order we will answer */
2307 if (!NT_STATUS_IS_OK(status)) {
2308 talloc_free(call);
2311 return status;
2314 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2315 struct loadparm_context *lp_ctx,
2316 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2318 NTSTATUS status;
2319 struct dcesrv_context *dce_ctx;
2320 int i;
2322 if (!endpoint_servers) {
2323 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2324 return NT_STATUS_INTERNAL_ERROR;
2327 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2328 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2330 if (uid_wrapper_enabled()) {
2331 setenv("UID_WRAPPER_MYUID", "1", 1);
2333 dce_ctx->initial_euid = geteuid();
2334 if (uid_wrapper_enabled()) {
2335 unsetenv("UID_WRAPPER_MYUID");
2338 dce_ctx->endpoint_list = NULL;
2339 dce_ctx->lp_ctx = lp_ctx;
2340 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2341 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2342 dce_ctx->broken_connections = NULL;
2344 for (i=0;endpoint_servers[i];i++) {
2345 const struct dcesrv_endpoint_server *ep_server;
2347 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2348 if (!ep_server) {
2349 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2350 return NT_STATUS_INTERNAL_ERROR;
2353 status = ep_server->init_server(dce_ctx, ep_server);
2354 if (!NT_STATUS_IS_OK(status)) {
2355 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2356 nt_errstr(status)));
2357 return status;
2361 *_dce_ctx = dce_ctx;
2362 return NT_STATUS_OK;
2365 /* the list of currently registered DCERPC endpoint servers.
2367 static struct ep_server {
2368 struct dcesrv_endpoint_server *ep_server;
2369 } *ep_servers = NULL;
2370 static int num_ep_servers;
2373 register a DCERPC endpoint server.
2375 The 'name' can be later used by other backends to find the operations
2376 structure for this backend.
2379 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2382 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2383 /* its already registered! */
2384 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2385 ep_server->name));
2386 return NT_STATUS_OBJECT_NAME_COLLISION;
2389 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2390 if (!ep_servers) {
2391 smb_panic("out of memory in dcerpc_register");
2394 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2395 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2397 num_ep_servers++;
2399 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2400 ep_server->name));
2402 return NT_STATUS_OK;
2406 return the operations structure for a named backend of the specified type
2408 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2410 int i;
2412 for (i=0;i<num_ep_servers;i++) {
2413 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2414 return ep_servers[i].ep_server;
2418 return NULL;
2421 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2423 static bool initialized;
2424 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2425 STATIC_dcerpc_server_MODULES_PROTO;
2426 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2427 init_module_fn *shared_init;
2429 if (initialized) {
2430 return;
2432 initialized = true;
2434 shared_init = load_samba_modules(NULL, "dcerpc_server");
2436 run_init_functions(NULL, static_init);
2437 run_init_functions(NULL, shared_init);
2439 talloc_free(shared_init);
2443 return the DCERPC module version, and the size of some critical types
2444 This can be used by endpoint server modules to either detect compilation errors, or provide
2445 multiple implementations for different smbd compilation options in one module
2447 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2449 static const struct dcesrv_critical_sizes critical_sizes = {
2450 DCERPC_MODULE_VERSION,
2451 sizeof(struct dcesrv_context),
2452 sizeof(struct dcesrv_endpoint),
2453 sizeof(struct dcesrv_endpoint_server),
2454 sizeof(struct dcesrv_interface),
2455 sizeof(struct dcesrv_if_list),
2456 sizeof(struct dcesrv_connection),
2457 sizeof(struct dcesrv_call_state),
2458 sizeof(struct dcesrv_auth),
2459 sizeof(struct dcesrv_handle)
2462 return &critical_sizes;
2465 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2467 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2468 struct stream_connection *srv_conn;
2469 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2470 struct stream_connection);
2472 dce_conn->wait_send = NULL;
2473 dce_conn->wait_recv = NULL;
2474 dce_conn->wait_private = NULL;
2476 dce_conn->allow_bind = false;
2477 dce_conn->allow_alter = false;
2479 dce_conn->default_auth_state->auth_invalid = true;
2481 if (dce_conn->pending_call_list == NULL) {
2482 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2484 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2485 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2486 return;
2489 if (dce_conn->terminate != NULL) {
2490 return;
2493 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2494 reason));
2495 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2496 if (dce_conn->terminate == NULL) {
2497 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2499 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2502 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2504 struct dcesrv_connection *cur, *next;
2506 next = dce_ctx->broken_connections;
2507 while (next != NULL) {
2508 cur = next;
2509 next = cur->next;
2511 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2512 struct dcesrv_connection_context *context_cur, *context_next;
2514 context_next = cur->contexts;
2515 while (context_next != NULL) {
2516 context_cur = context_next;
2517 context_next = context_cur->next;
2519 dcesrv_connection_context_destructor(context_cur);
2523 dcesrv_terminate_connection(cur, cur->terminate);
2527 /* We need this include to be able to compile on some plateforms
2528 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2529 * correctly.
2530 * It has to be that deep because otherwise we have a conflict on
2531 * const struct dcesrv_interface declaration.
2532 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2533 * which conflict with the bind used before.
2535 #include "system/network.h"
2537 struct dcesrv_sock_reply_state {
2538 struct dcesrv_connection *dce_conn;
2539 struct dcesrv_call_state *call;
2540 struct iovec iov;
2543 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2544 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2546 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2548 struct dcesrv_call_state *call;
2550 call = dce_conn->call_list;
2551 if (!call || !call->replies) {
2552 return;
2555 while (call->replies) {
2556 struct data_blob_list_item *rep = call->replies;
2557 struct dcesrv_sock_reply_state *substate;
2558 struct tevent_req *subreq;
2560 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2561 if (!substate) {
2562 dcesrv_terminate_connection(dce_conn, "no memory");
2563 return;
2566 substate->dce_conn = dce_conn;
2567 substate->call = NULL;
2569 DLIST_REMOVE(call->replies, rep);
2571 if (call->replies == NULL && call->terminate_reason == NULL) {
2572 substate->call = call;
2575 substate->iov.iov_base = (void *) rep->blob.data;
2576 substate->iov.iov_len = rep->blob.length;
2578 subreq = tstream_writev_queue_send(substate,
2579 dce_conn->event_ctx,
2580 dce_conn->stream,
2581 dce_conn->send_queue,
2582 &substate->iov, 1);
2583 if (!subreq) {
2584 dcesrv_terminate_connection(dce_conn, "no memory");
2585 return;
2587 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2588 substate);
2591 if (call->terminate_reason != NULL) {
2592 struct tevent_req *subreq;
2594 subreq = tevent_queue_wait_send(call,
2595 dce_conn->event_ctx,
2596 dce_conn->send_queue);
2597 if (!subreq) {
2598 dcesrv_terminate_connection(dce_conn, __location__);
2599 return;
2601 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2602 call);
2605 DLIST_REMOVE(call->conn->call_list, call);
2606 call->list = DCESRV_LIST_NONE;
2609 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2611 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2612 struct dcesrv_sock_reply_state);
2613 int ret;
2614 int sys_errno;
2615 NTSTATUS status;
2616 struct dcesrv_call_state *call = substate->call;
2618 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2619 TALLOC_FREE(subreq);
2620 if (ret == -1) {
2621 status = map_nt_error_from_unix_common(sys_errno);
2622 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2623 return;
2626 talloc_free(substate);
2627 if (call) {
2628 talloc_free(call);
2632 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2634 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2636 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2637 struct dcesrv_call_state);
2638 bool ok;
2639 struct timeval tv;
2641 /* make sure we stop send queue before removing subreq */
2642 tevent_queue_stop(call->conn->send_queue);
2644 ok = tevent_queue_wait_recv(subreq);
2645 TALLOC_FREE(subreq);
2646 if (!ok) {
2647 dcesrv_terminate_connection(call->conn, __location__);
2648 return;
2651 /* disconnect after 200 usecs */
2652 tv = timeval_current_ofs_usec(200);
2653 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2654 if (subreq == NULL) {
2655 dcesrv_terminate_connection(call->conn, __location__);
2656 return;
2658 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2659 call);
2662 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2664 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2665 struct dcesrv_call_state);
2666 bool ok;
2668 ok = tevent_wakeup_recv(subreq);
2669 TALLOC_FREE(subreq);
2670 if (!ok) {
2671 dcesrv_terminate_connection(call->conn, __location__);
2672 return;
2675 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2678 struct dcesrv_socket_context {
2679 const struct dcesrv_endpoint *endpoint;
2680 struct dcesrv_context *dcesrv_ctx;
2684 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2686 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2688 NTSTATUS status;
2689 struct dcesrv_socket_context *dcesrv_sock =
2690 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2691 enum dcerpc_transport_t transport =
2692 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2693 struct dcesrv_connection *dcesrv_conn = NULL;
2694 int ret;
2695 struct tevent_req *subreq;
2696 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2698 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2700 if (!srv_conn->session_info) {
2701 status = auth_anonymous_session_info(srv_conn,
2702 lp_ctx,
2703 &srv_conn->session_info);
2704 if (!NT_STATUS_IS_OK(status)) {
2705 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2706 nt_errstr(status)));
2707 stream_terminate_connection(srv_conn, nt_errstr(status));
2708 return;
2713 * This fills in dcesrv_conn->endpoint with the endpoint
2714 * associated with the socket. From this point on we know
2715 * which (group of) services we are handling, but not the
2716 * specific interface.
2719 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2720 srv_conn,
2721 dcesrv_sock->endpoint,
2722 srv_conn->session_info,
2723 srv_conn->event.ctx,
2724 srv_conn->msg_ctx,
2725 srv_conn->server_id,
2726 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2727 &dcesrv_conn);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2730 nt_errstr(status)));
2731 stream_terminate_connection(srv_conn, nt_errstr(status));
2732 return;
2735 dcesrv_conn->transport.private_data = srv_conn;
2736 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2738 TALLOC_FREE(srv_conn->event.fde);
2740 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2741 if (!dcesrv_conn->send_queue) {
2742 status = NT_STATUS_NO_MEMORY;
2743 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2744 nt_errstr(status)));
2745 stream_terminate_connection(srv_conn, nt_errstr(status));
2746 return;
2749 if (transport == NCACN_NP) {
2750 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2751 &srv_conn->tstream);
2752 } else {
2753 ret = tstream_bsd_existing_socket(dcesrv_conn,
2754 socket_get_fd(srv_conn->socket),
2755 &dcesrv_conn->stream);
2756 if (ret == -1) {
2757 status = map_nt_error_from_unix_common(errno);
2758 DEBUG(0, ("dcesrv_sock_accept: "
2759 "failed to setup tstream: %s\n",
2760 nt_errstr(status)));
2761 stream_terminate_connection(srv_conn, nt_errstr(status));
2762 return;
2764 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2767 dcesrv_conn->local_address = srv_conn->local_address;
2768 dcesrv_conn->remote_address = srv_conn->remote_address;
2770 if (transport == NCALRPC) {
2771 uid_t uid;
2772 gid_t gid;
2773 int sock_fd;
2775 sock_fd = socket_get_fd(srv_conn->socket);
2776 if (sock_fd == -1) {
2777 stream_terminate_connection(
2778 srv_conn, "socket_get_fd failed\n");
2779 return;
2782 ret = getpeereid(sock_fd, &uid, &gid);
2783 if (ret == -1) {
2784 status = map_nt_error_from_unix_common(errno);
2785 DEBUG(0, ("dcesrv_sock_accept: "
2786 "getpeereid() failed for NCALRPC: %s\n",
2787 nt_errstr(status)));
2788 stream_terminate_connection(srv_conn, nt_errstr(status));
2789 return;
2791 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2792 struct tsocket_address *r = NULL;
2794 ret = tsocket_address_unix_from_path(dcesrv_conn,
2795 AS_SYSTEM_MAGIC_PATH_TOKEN,
2796 &r);
2797 if (ret == -1) {
2798 status = map_nt_error_from_unix_common(errno);
2799 DEBUG(0, ("dcesrv_sock_accept: "
2800 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2801 nt_errstr(status)));
2802 stream_terminate_connection(srv_conn, nt_errstr(status));
2803 return;
2805 dcesrv_conn->remote_address = r;
2809 srv_conn->private_data = dcesrv_conn;
2811 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2812 dcesrv_conn->event_ctx,
2813 dcesrv_conn->stream);
2814 if (!subreq) {
2815 status = NT_STATUS_NO_MEMORY;
2816 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2817 nt_errstr(status)));
2818 stream_terminate_connection(srv_conn, nt_errstr(status));
2819 return;
2821 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2823 return;
2826 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2828 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2830 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2831 struct dcesrv_connection);
2832 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2833 struct ncacn_packet *pkt;
2834 DATA_BLOB buffer;
2835 NTSTATUS status;
2837 if (dce_conn->terminate) {
2839 * if the current connection is broken
2840 * we need to clean it up before any other connection
2842 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2843 dcesrv_cleanup_broken_connections(dce_ctx);
2844 return;
2847 dcesrv_cleanup_broken_connections(dce_ctx);
2849 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2850 &pkt, &buffer);
2851 TALLOC_FREE(subreq);
2852 if (!NT_STATUS_IS_OK(status)) {
2853 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2854 return;
2857 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2858 if (!NT_STATUS_IS_OK(status)) {
2859 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2860 return;
2864 * This is used to block the connection during
2865 * pending authentication.
2867 if (dce_conn->wait_send != NULL) {
2868 subreq = dce_conn->wait_send(dce_conn,
2869 dce_conn->event_ctx,
2870 dce_conn->wait_private);
2871 if (!subreq) {
2872 status = NT_STATUS_NO_MEMORY;
2873 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2874 return;
2876 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2877 return;
2880 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2881 dce_conn->event_ctx,
2882 dce_conn->stream);
2883 if (!subreq) {
2884 status = NT_STATUS_NO_MEMORY;
2885 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2886 return;
2888 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2891 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2893 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2894 struct dcesrv_connection);
2895 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2896 NTSTATUS status;
2898 if (dce_conn->terminate) {
2900 * if the current connection is broken
2901 * we need to clean it up before any other connection
2903 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2904 dcesrv_cleanup_broken_connections(dce_ctx);
2905 return;
2908 dcesrv_cleanup_broken_connections(dce_ctx);
2910 status = dce_conn->wait_recv(subreq);
2911 dce_conn->wait_send = NULL;
2912 dce_conn->wait_recv = NULL;
2913 dce_conn->wait_private = NULL;
2914 TALLOC_FREE(subreq);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2917 return;
2920 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2921 dce_conn->event_ctx,
2922 dce_conn->stream);
2923 if (!subreq) {
2924 status = NT_STATUS_NO_MEMORY;
2925 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2926 return;
2928 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2931 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2933 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2934 struct dcesrv_connection);
2935 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2938 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2940 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2941 struct dcesrv_connection);
2942 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2946 static const struct stream_server_ops dcesrv_stream_ops = {
2947 .name = "rpc",
2948 .accept_connection = dcesrv_sock_accept,
2949 .recv_handler = dcesrv_sock_recv,
2950 .send_handler = dcesrv_sock_send,
2953 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2954 struct loadparm_context *lp_ctx,
2955 struct dcesrv_endpoint *e,
2956 struct tevent_context *event_ctx,
2957 const struct model_ops *model_ops,
2958 void *process_context)
2960 struct dcesrv_socket_context *dcesrv_sock;
2961 uint16_t port = 1;
2962 NTSTATUS status;
2963 const char *endpoint;
2965 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2966 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2968 /* remember the endpoint of this socket */
2969 dcesrv_sock->endpoint = e;
2970 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2972 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2974 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2975 model_ops, &dcesrv_stream_ops,
2976 "unix", endpoint, &port,
2977 lpcfg_socket_options(lp_ctx),
2978 dcesrv_sock, process_context);
2979 if (!NT_STATUS_IS_OK(status)) {
2980 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2981 endpoint, nt_errstr(status)));
2984 return status;
2987 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2988 struct loadparm_context *lp_ctx,
2989 struct dcesrv_endpoint *e,
2990 struct tevent_context *event_ctx,
2991 const struct model_ops *model_ops,
2992 void *process_context)
2994 struct dcesrv_socket_context *dcesrv_sock;
2995 uint16_t port = 1;
2996 char *full_path;
2997 NTSTATUS status;
2998 const char *endpoint;
3000 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3002 if (endpoint == NULL) {
3004 * No identifier specified: use DEFAULT.
3006 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
3007 * no endpoint and let the epmapper worry about it.
3009 endpoint = "DEFAULT";
3010 status = dcerpc_binding_set_string_option(e->ep_description,
3011 "endpoint",
3012 endpoint);
3013 if (!NT_STATUS_IS_OK(status)) {
3014 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
3015 nt_errstr(status)));
3016 return status;
3020 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
3021 endpoint);
3023 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3024 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3026 /* remember the endpoint of this socket */
3027 dcesrv_sock->endpoint = e;
3028 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3030 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
3031 model_ops, &dcesrv_stream_ops,
3032 "unix", full_path, &port,
3033 lpcfg_socket_options(lp_ctx),
3034 dcesrv_sock, process_context);
3035 if (!NT_STATUS_IS_OK(status)) {
3036 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
3037 endpoint, full_path, nt_errstr(status)));
3039 return status;
3042 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
3043 struct loadparm_context *lp_ctx,
3044 struct dcesrv_endpoint *e,
3045 struct tevent_context *event_ctx,
3046 const struct model_ops *model_ops,
3047 void *process_context)
3049 struct dcesrv_socket_context *dcesrv_sock;
3050 NTSTATUS status;
3051 const char *endpoint;
3053 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3054 if (endpoint == NULL) {
3055 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
3056 return NT_STATUS_INVALID_PARAMETER;
3059 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3060 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3062 /* remember the endpoint of this socket */
3063 dcesrv_sock->endpoint = e;
3064 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3066 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
3067 model_ops, &dcesrv_stream_ops,
3068 endpoint,
3069 dcesrv_sock, process_context);
3070 if (!NT_STATUS_IS_OK(status)) {
3071 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
3072 endpoint, nt_errstr(status)));
3073 return status;
3076 return NT_STATUS_OK;
3080 add a socket address to the list of events, one event per dcerpc endpoint
3082 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3083 struct dcesrv_endpoint *e,
3084 struct tevent_context *event_ctx,
3085 const struct model_ops *model_ops,
3086 const char *address,
3087 void *process_context)
3089 struct dcesrv_socket_context *dcesrv_sock;
3090 uint16_t port = 0;
3091 NTSTATUS status;
3092 const char *endpoint;
3093 char port_str[6];
3095 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3096 if (endpoint != NULL) {
3097 port = atoi(endpoint);
3100 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3101 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3103 /* remember the endpoint of this socket */
3104 dcesrv_sock->endpoint = e;
3105 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3107 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3108 model_ops, &dcesrv_stream_ops,
3109 "ip", address, &port,
3110 lpcfg_socket_options(dce_ctx->lp_ctx),
3111 dcesrv_sock, process_context);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 struct dcesrv_if_list *iface;
3114 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3115 address, port));
3116 for (iface = e->interface_list; iface; iface = iface->next) {
3117 DEBUGADD(0, ("%s ", iface->iface.name));
3119 DEBUGADD(0, ("failed - %s",
3120 nt_errstr(status)));
3121 return status;
3124 snprintf(port_str, sizeof(port_str), "%u", port);
3126 status = dcerpc_binding_set_string_option(e->ep_description,
3127 "endpoint", port_str);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3130 port_str, nt_errstr(status)));
3131 return status;
3132 } else {
3133 struct dcesrv_if_list *iface;
3134 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3135 address, port_str));
3136 for (iface = e->interface_list; iface; iface = iface->next) {
3137 DEBUGADD(4, ("%s ", iface->iface.name));
3139 DEBUGADD(4, ("\n"));
3142 return NT_STATUS_OK;
3145 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3147 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3148 struct loadparm_context *lp_ctx,
3149 struct dcesrv_endpoint *e,
3150 struct tevent_context *event_ctx,
3151 const struct model_ops *model_ops,
3152 void *process_context)
3154 NTSTATUS status;
3156 /* Add TCP/IP sockets */
3157 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3158 int num_interfaces;
3159 int i;
3160 struct interface *ifaces;
3162 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3164 num_interfaces = iface_list_count(ifaces);
3165 for(i = 0; i < num_interfaces; i++) {
3166 const char *address = iface_list_n_ip(ifaces, i);
3167 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3168 model_ops, address,
3169 process_context);
3170 NT_STATUS_NOT_OK_RETURN(status);
3172 } else {
3173 char **wcard;
3174 size_t i;
3175 size_t num_binds = 0;
3176 wcard = iface_list_wildcard(dce_ctx);
3177 NT_STATUS_HAVE_NO_MEMORY(wcard);
3178 for (i=0; wcard[i]; i++) {
3179 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3180 model_ops, wcard[i],
3181 process_context);
3182 if (NT_STATUS_IS_OK(status)) {
3183 num_binds++;
3186 talloc_free(wcard);
3187 if (num_binds == 0) {
3188 return NT_STATUS_INVALID_PARAMETER_MIX;
3192 return NT_STATUS_OK;
3195 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3196 struct loadparm_context *lp_ctx,
3197 struct dcesrv_endpoint *e,
3198 struct tevent_context *event_ctx,
3199 const struct model_ops *model_ops,
3200 void *process_context)
3202 enum dcerpc_transport_t transport =
3203 dcerpc_binding_get_transport(e->ep_description);
3205 switch (transport) {
3206 case NCACN_UNIX_STREAM:
3207 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3208 model_ops, process_context);
3210 case NCALRPC:
3211 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3212 model_ops, process_context);
3214 case NCACN_IP_TCP:
3215 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3216 model_ops, process_context);
3218 case NCACN_NP:
3219 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3220 model_ops, process_context);
3222 default:
3223 return NT_STATUS_NOT_SUPPORTED;
3229 * retrieve credentials from a dce_call
3231 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3233 struct dcesrv_auth *auth = dce_call->auth_state;
3234 return auth->session_info->credentials;
3238 * returns true if this is an authenticated call
3240 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3242 struct dcesrv_auth *auth = dce_call->auth_state;
3243 enum security_user_level level;
3244 level = security_session_user_level(auth->session_info, NULL);
3245 return level >= SECURITY_USER;
3249 * retrieve account_name for a dce_call
3251 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3253 struct dcesrv_auth *auth = dce_call->auth_state;
3254 return auth->session_info->info->account_name;
3258 * retrieve session_info from a dce_call
3260 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3262 struct dcesrv_auth *auth = dce_call->auth_state;
3263 return auth->session_info;
3267 * retrieve auth type/level from a dce_call
3269 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3270 enum dcerpc_AuthType *auth_type,
3271 enum dcerpc_AuthLevel *auth_level)
3273 struct dcesrv_auth *auth = dce_call->auth_state;
3275 if (auth_type != NULL) {
3276 *auth_type = auth->auth_type;
3278 if (auth_level != NULL) {
3279 *auth_level = auth->auth_level;