s4:rpc_server: implement async BIND using gensec_update_send/recv
[Samba.git] / source4 / rpc_server / dcerpc_server.c
blob225f5e721e558347e9bec07788c0e2a786566c9c
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, uint16_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;
280 * If we are not using handles, there is no need for force
281 * this service into using a single process.
283 * However, due to the way we listen for RPC packets, we can
284 * only do this if we have a single service per pipe or TCP
285 * port, so we still force a single combined process for
286 * ncalrpc.
288 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
289 use_single_process = false;
292 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
294 if (NT_STATUS_IS_ERR(status)) {
295 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
296 return status;
299 transport = dcerpc_binding_get_transport(binding);
300 if (transport == NCACN_IP_TCP) {
301 int port;
302 char port_str[6];
305 * First check if there is already a port specified, eg
306 * for epmapper on ncacn_ip_tcp:[135]
308 const char *endpoint
309 = dcerpc_binding_get_string_option(binding,
310 "endpoint");
311 if (endpoint == NULL) {
312 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
313 "rpc server port", iface->name, 0);
316 * For RPC services that are not set to use a single
317 * process, we do not default to using the 'rpc server
318 * port' because that would cause a double-bind on
319 * that port.
321 if (port == 0 && !use_single_process) {
322 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
324 if (port != 0) {
325 snprintf(port_str, sizeof(port_str), "%u", port);
326 status = dcerpc_binding_set_string_option(binding,
327 "endpoint",
328 port_str);
329 if (!NT_STATUS_IS_OK(status)) {
330 return status;
336 /* see if the interface is already registered on the endpoint */
337 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
338 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
339 iface->name, ep_name));
340 return NT_STATUS_OBJECT_NAME_COLLISION;
343 /* check if this endpoint exists
345 ep = find_endpoint(dce_ctx, binding);
347 if (ep != NULL) {
349 * We want a new port on ncacn_ip_tcp for NETLOGON, so
350 * it can be multi-process. Other processes can also
351 * listen on distinct ports, if they have one forced
352 * in the code above with eg 'rpc server port:drsuapi = 1027'
354 * If we have mulitiple endpoints on port 0, they each
355 * get an epemeral port (currently by walking up from
356 * 1024).
358 if (!use_single_process && transport == NCACN_IP_TCP) {
359 add_ep = true;
363 if (ep == NULL || add_ep) {
364 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
365 if (!ep) {
366 return NT_STATUS_NO_MEMORY;
368 ZERO_STRUCTP(ep);
369 ep->ep_description = talloc_move(ep, &binding);
370 add_ep = true;
372 /* add mgmt interface */
373 ifl = talloc_zero(ep, struct dcesrv_if_list);
374 if (!ifl) {
375 return NT_STATUS_NO_MEMORY;
378 ifl->iface = dcesrv_get_mgmt_interface();
380 DLIST_ADD(ep->interface_list, ifl);
384 * By default don't force into a single process, but if any
385 * interface on this endpoint on this service uses handles
386 * (most do), then we must force into single process mode
388 * By overwriting this each time a new interface is added to
389 * this endpoint, we end up with the most restrictive setting.
391 if (use_single_process) {
392 ep->use_single_process = true;
395 /* talloc a new interface list element */
396 ifl = talloc_zero(ep, struct dcesrv_if_list);
397 if (!ifl) {
398 return NT_STATUS_NO_MEMORY;
401 /* copy the given interface struct to the one on the endpoints interface list */
402 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
404 /* if we have a security descriptor given,
405 * we should see if we can set it up on the endpoint
407 if (sd != NULL) {
408 /* if there's currently no security descriptor given on the endpoint
409 * we try to set it
411 if (ep->sd == NULL) {
412 ep->sd = security_descriptor_copy(ep, sd);
415 /* if now there's no security descriptor given on the endpoint
416 * something goes wrong, either we failed to copy the security descriptor
417 * or there was already one on the endpoint
419 if (ep->sd != NULL) {
420 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
421 " on endpoint '%s'\n",
422 iface->name, ep_name));
423 if (add_ep) free(ep);
424 free(ifl);
425 return NT_STATUS_OBJECT_NAME_COLLISION;
429 /* finally add the interface on the endpoint */
430 DLIST_ADD(ep->interface_list, ifl);
432 /* if it's a new endpoint add it to the dcesrv_context */
433 if (add_ep) {
434 DLIST_ADD(dce_ctx->endpoint_list, ep);
437 /* Re-get the string as we may have set a port */
438 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
440 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
441 iface->name, ep_string));
442 TALLOC_FREE(ep_string);
444 return NT_STATUS_OK;
447 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
448 DATA_BLOB *session_key)
450 if (p->auth_state.session_info->session_key.length) {
451 *session_key = p->auth_state.session_info->session_key;
452 return NT_STATUS_OK;
454 return NT_STATUS_NO_USER_SESSION_KEY;
458 fetch the user session key - may be default (above) or the SMB session key
460 The key is always truncated to 16 bytes
462 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
463 DATA_BLOB *session_key)
465 NTSTATUS status = p->auth_state.session_key(p, session_key);
466 if (!NT_STATUS_IS_OK(status)) {
467 return status;
470 session_key->length = MIN(session_key->length, 16);
472 return NT_STATUS_OK;
476 connect to a dcerpc endpoint
478 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
479 TALLOC_CTX *mem_ctx,
480 const struct dcesrv_endpoint *ep,
481 struct auth_session_info *session_info,
482 struct tevent_context *event_ctx,
483 struct imessaging_context *msg_ctx,
484 struct server_id server_id,
485 uint32_t state_flags,
486 struct dcesrv_connection **_p)
488 struct dcesrv_connection *p;
490 if (!session_info) {
491 return NT_STATUS_ACCESS_DENIED;
494 p = talloc_zero(mem_ctx, struct dcesrv_connection);
495 NT_STATUS_HAVE_NO_MEMORY(p);
497 if (!talloc_reference(p, session_info)) {
498 talloc_free(p);
499 return NT_STATUS_NO_MEMORY;
502 p->dce_ctx = dce_ctx;
503 p->endpoint = ep;
504 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
505 p->auth_state.session_info = session_info;
506 p->auth_state.session_key = dcesrv_generic_session_key;
507 p->event_ctx = event_ctx;
508 p->msg_ctx = msg_ctx;
509 p->server_id = server_id;
510 p->state_flags = state_flags;
511 p->allow_bind = true;
512 p->max_recv_frag = 5840;
513 p->max_xmit_frag = 5840;
514 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
517 * For now we only support NDR32.
519 p->preferred_transfer = &ndr_transfer_syntax_ndr;
521 *_p = p;
522 return NT_STATUS_OK;
526 move a call from an existing linked list to the specified list. This
527 prevents bugs where we forget to remove the call from a previous
528 list when moving it.
530 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
531 enum dcesrv_call_list list)
533 switch (call->list) {
534 case DCESRV_LIST_NONE:
535 break;
536 case DCESRV_LIST_CALL_LIST:
537 DLIST_REMOVE(call->conn->call_list, call);
538 break;
539 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
540 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
541 break;
542 case DCESRV_LIST_PENDING_CALL_LIST:
543 DLIST_REMOVE(call->conn->pending_call_list, call);
544 break;
546 call->list = list;
547 switch (list) {
548 case DCESRV_LIST_NONE:
549 break;
550 case DCESRV_LIST_CALL_LIST:
551 DLIST_ADD_END(call->conn->call_list, call);
552 break;
553 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
554 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
555 break;
556 case DCESRV_LIST_PENDING_CALL_LIST:
557 DLIST_ADD_END(call->conn->pending_call_list, call);
558 break;
562 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
563 const char *reason)
565 if (call->conn->terminate != NULL) {
566 return;
569 call->conn->allow_bind = false;
570 call->conn->allow_alter = false;
571 call->conn->allow_auth3 = false;
572 call->conn->allow_request = false;
574 call->terminate_reason = talloc_strdup(call, reason);
575 if (call->terminate_reason == NULL) {
576 call->terminate_reason = __location__;
581 return a dcerpc bind_nak
583 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
585 struct ncacn_packet pkt;
586 struct dcerpc_bind_nak_version version;
587 struct data_blob_list_item *rep;
588 NTSTATUS status;
589 static const uint8_t _pad[3] = { 0, };
592 * We add the call to the pending_call_list
593 * in order to defer the termination.
595 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
597 /* setup a bind_nak */
598 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
599 pkt.auth_length = 0;
600 pkt.call_id = call->pkt.call_id;
601 pkt.ptype = DCERPC_PKT_BIND_NAK;
602 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
603 pkt.u.bind_nak.reject_reason = reason;
604 version.rpc_vers = 5;
605 version.rpc_vers_minor = 0;
606 pkt.u.bind_nak.num_versions = 1;
607 pkt.u.bind_nak.versions = &version;
608 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
610 rep = talloc_zero(call, struct data_blob_list_item);
611 if (!rep) {
612 return NT_STATUS_NO_MEMORY;
615 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
616 if (!NT_STATUS_IS_OK(status)) {
617 return status;
620 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
622 DLIST_ADD_END(call->replies, rep);
623 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
625 if (call->conn->call_list && call->conn->call_list->replies) {
626 if (call->conn->transport.report_output_data) {
627 call->conn->transport.report_output_data(call->conn);
631 return NT_STATUS_OK;
634 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
635 uint32_t fault_code)
638 * We add the call to the pending_call_list
639 * in order to defer the termination.
641 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
643 return dcesrv_fault_with_flags(call, fault_code,
644 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
647 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
649 DLIST_REMOVE(c->conn->contexts, c);
651 if (c->iface && c->iface->unbind) {
652 c->iface->unbind(c, c->iface);
653 c->iface = NULL;
656 return 0;
659 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
661 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
662 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
663 enum dcerpc_transport_t transport =
664 dcerpc_binding_get_transport(endpoint->ep_description);
665 struct dcesrv_connection_context *context = dce_call->context;
666 const struct dcesrv_interface *iface = context->iface;
668 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
670 if (transport == NCALRPC) {
671 context->allow_connect = true;
672 return;
676 * allow overwrite per interface
677 * allow dcerpc auth level connect:<interface>
679 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
680 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
681 "allow dcerpc auth level connect",
682 iface->name,
683 context->allow_connect);
686 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
687 const struct dcesrv_interface *iface)
689 if (dce_call->context == NULL) {
690 return NT_STATUS_INTERNAL_ERROR;
694 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
695 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
697 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
698 return NT_STATUS_OK;
701 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
702 const struct dcesrv_interface *iface)
704 if (dce_call->context == NULL) {
705 return NT_STATUS_INTERNAL_ERROR;
708 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
709 return NT_STATUS_OK;
712 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
713 const struct dcesrv_interface *iface)
715 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
716 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
717 enum dcerpc_transport_t transport =
718 dcerpc_binding_get_transport(endpoint->ep_description);
719 struct dcesrv_connection_context *context = dce_call->context;
721 if (context == NULL) {
722 return NT_STATUS_INTERNAL_ERROR;
725 if (transport == NCALRPC) {
726 context->allow_connect = true;
727 return NT_STATUS_OK;
731 * allow overwrite per interface
732 * allow dcerpc auth level connect:<interface>
734 context->allow_connect = false;
735 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
736 "allow dcerpc auth level connect",
737 iface->name,
738 context->allow_connect);
739 return NT_STATUS_OK;
742 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
743 const struct dcesrv_interface *iface)
745 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
746 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
747 enum dcerpc_transport_t transport =
748 dcerpc_binding_get_transport(endpoint->ep_description);
749 struct dcesrv_connection_context *context = dce_call->context;
751 if (context == NULL) {
752 return NT_STATUS_INTERNAL_ERROR;
755 if (transport == NCALRPC) {
756 context->allow_connect = true;
757 return NT_STATUS_OK;
761 * allow overwrite per interface
762 * allow dcerpc auth level connect:<interface>
764 context->allow_connect = true;
765 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
766 "allow dcerpc auth level connect",
767 iface->name,
768 context->allow_connect);
769 return NT_STATUS_OK;
772 struct dcesrv_conn_auth_wait_context {
773 struct tevent_req *req;
774 bool done;
775 NTSTATUS status;
778 struct dcesrv_conn_auth_wait_state {
779 uint8_t dummy;
782 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
783 struct tevent_context *ev,
784 void *private_data)
786 struct dcesrv_conn_auth_wait_context *auth_wait =
787 talloc_get_type_abort(private_data,
788 struct dcesrv_conn_auth_wait_context);
789 struct tevent_req *req = NULL;
790 struct dcesrv_conn_auth_wait_state *state = NULL;
792 req = tevent_req_create(mem_ctx, &state,
793 struct dcesrv_conn_auth_wait_state);
794 if (req == NULL) {
795 return NULL;
797 auth_wait->req = req;
799 tevent_req_defer_callback(req, ev);
801 if (!auth_wait->done) {
802 return req;
805 if (tevent_req_nterror(req, auth_wait->status)) {
806 return tevent_req_post(req, ev);
809 tevent_req_done(req);
810 return tevent_req_post(req, ev);
813 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
815 return tevent_req_simple_recv_ntstatus(req);
818 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
820 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
822 if (conn->wait_send != NULL) {
823 return NT_STATUS_INTERNAL_ERROR;
826 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
827 if (auth_wait == NULL) {
828 return NT_STATUS_NO_MEMORY;
831 conn->wait_private = auth_wait;
832 conn->wait_send = dcesrv_conn_auth_wait_send;
833 conn->wait_recv = dcesrv_conn_auth_wait_recv;
834 return NT_STATUS_OK;
837 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
838 NTSTATUS status)
840 struct dcesrv_conn_auth_wait_context *auth_wait =
841 talloc_get_type_abort(conn->wait_private,
842 struct dcesrv_conn_auth_wait_context);
844 auth_wait->done = true;
845 auth_wait->status = status;
847 if (auth_wait->req == NULL) {
848 return;
851 if (tevent_req_nterror(auth_wait->req, status)) {
852 return;
855 tevent_req_done(auth_wait->req);
858 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
860 static void dcesrv_bind_done(struct tevent_req *subreq);
863 handle a bind request
865 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
867 struct dcesrv_connection *conn = call->conn;
868 struct ncacn_packet *pkt = &call->ack_pkt;
869 NTSTATUS status;
870 uint32_t extra_flags = 0;
871 uint16_t max_req = 0;
872 uint16_t max_rep = 0;
873 const char *ep_prefix = "";
874 const char *endpoint = NULL;
875 struct dcesrv_auth *auth = &call->conn->auth_state;
876 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
877 struct dcerpc_ack_ctx *ack_features = NULL;
878 struct tevent_req *subreq = NULL;
879 size_t i;
881 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
882 DCERPC_PKT_BIND,
883 call->pkt.u.bind.auth_info.length,
884 0, /* required flags */
885 DCERPC_PFC_FLAG_FIRST |
886 DCERPC_PFC_FLAG_LAST |
887 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
888 0x08 | /* this is not defined, but should be ignored */
889 DCERPC_PFC_FLAG_CONC_MPX |
890 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
891 DCERPC_PFC_FLAG_MAYBE |
892 DCERPC_PFC_FLAG_OBJECT_UUID);
893 if (!NT_STATUS_IS_OK(status)) {
894 return dcesrv_bind_nak(call,
895 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
898 /* max_recv_frag and max_xmit_frag result always in the same value! */
899 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
900 call->pkt.u.bind.max_recv_frag);
902 * The values are between 2048 and 5840 tested against Windows 2012R2
903 * via ncacn_ip_tcp on port 135.
905 max_req = MAX(2048, max_req);
906 max_rep = MIN(max_req, call->conn->max_recv_frag);
907 /* They are truncated to an 8 byte boundary. */
908 max_rep &= 0xFFF8;
910 /* max_recv_frag and max_xmit_frag result always in the same value! */
911 call->conn->max_recv_frag = max_rep;
912 call->conn->max_xmit_frag = max_rep;
915 if provided, check the assoc_group is valid
917 if (call->pkt.u.bind.assoc_group_id != 0) {
918 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
919 call->conn->dce_ctx,
920 call->pkt.u.bind.assoc_group_id);
921 } else {
922 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
923 call->conn->dce_ctx);
927 * The NETLOGON server does not use handles and so
928 * there is no need to support association groups, but
929 * we need to give back a number regardless.
931 * We have to do this when it is not run as a single process,
932 * because then it can't see the other valid association
933 * groups. We handle this genericly for all endpoints not
934 * running in single process mode.
936 * We know which endpoint we are on even before checking the
937 * iface UUID, so for simplicity we enforce the same policy
938 * for all interfaces on the endpoint.
940 * This means that where NETLOGON
941 * shares an endpoint (such as ncalrpc or of 'lsa over
942 * netlogon' is set) we will still check association groups.
946 if (call->conn->assoc_group == NULL &&
947 !call->conn->endpoint->use_single_process) {
948 call->conn->assoc_group
949 = dcesrv_assoc_group_new(call->conn,
950 call->conn->dce_ctx);
952 if (call->conn->assoc_group == NULL) {
953 return dcesrv_bind_nak(call, 0);
956 if (call->pkt.u.bind.num_contexts < 1) {
957 return dcesrv_bind_nak(call, 0);
960 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
961 call->pkt.u.bind.num_contexts);
962 if (ack_ctx_list == NULL) {
963 return dcesrv_bind_nak(call, 0);
967 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
968 * dcesrv_check_or_create_context()) and do some protocol validation
969 * and set sane defaults.
971 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
972 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
973 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
974 bool is_feature = false;
975 uint64_t features = 0;
977 if (c->num_transfer_syntaxes == 0) {
978 return dcesrv_bind_nak(call, 0);
981 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
982 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
985 * It's only treated as bind time feature request, if the first
986 * transfer_syntax matches, all others are ignored.
988 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
989 &features);
990 if (!is_feature) {
991 continue;
994 if (ack_features != NULL) {
996 * Only one bind time feature context is allowed.
998 return dcesrv_bind_nak(call, 0);
1000 ack_features = a;
1002 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1003 a->reason.negotiate = 0;
1004 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1005 /* not supported yet */
1007 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1008 a->reason.negotiate |=
1009 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1012 call->conn->bind_time_features = a->reason.negotiate;
1016 * Try to negotiate one new presentation context.
1018 * Deep in here we locate the iface (by uuid) that the client
1019 * requested, from the list of interfaces on the
1020 * call->conn->endpoint, and call iface->bind() on that iface.
1022 * call->conn was set up at the accept() of the socket, and
1023 * call->conn->endpoint has a list of interfaces restricted to
1024 * this port or pipe.
1026 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1027 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1028 return dcesrv_bind_nak(call, 0);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 return status;
1035 * At this point we still don't know which interface (eg
1036 * netlogon, lsa, drsuapi) the caller requested in this bind!
1037 * The most recently added context is available as the first
1038 * element in the linked list at call->conn->contexts, that is
1039 * call->conn->contexts->iface, but they may not have
1040 * requested one at all!
1043 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1044 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1045 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1046 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1049 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1050 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1054 * After finding the interface and setting up the NDR
1055 * transport negotiation etc, handle any authentication that
1056 * is being requested.
1058 if (!dcesrv_auth_bind(call)) {
1060 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1062 * With DCERPC_AUTH_LEVEL_NONE, we get the
1063 * reject_reason in auth->auth_context_id.
1065 return dcesrv_bind_nak(call, auth->auth_context_id);
1069 * This must a be a temporary failure e.g. talloc or invalid
1070 * configuration, e.g. no machine account.
1072 return dcesrv_bind_nak(call,
1073 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1076 /* setup a bind_ack */
1077 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1078 pkt->auth_length = 0;
1079 pkt->call_id = call->pkt.call_id;
1080 pkt->ptype = DCERPC_PKT_BIND_ACK;
1081 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1082 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1083 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1084 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1086 endpoint = dcerpc_binding_get_string_option(
1087 call->conn->endpoint->ep_description,
1088 "endpoint");
1089 if (endpoint == NULL) {
1090 endpoint = "";
1093 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1095 * TODO: check if this is really needed
1097 * Or if we should fix this in our idl files.
1099 ep_prefix = "\\PIPE\\";
1100 endpoint += 6;
1103 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1104 ep_prefix,
1105 endpoint);
1106 if (pkt->u.bind_ack.secondary_address == NULL) {
1107 return NT_STATUS_NO_MEMORY;
1109 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1110 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1111 pkt->u.bind_ack.auth_info = data_blob_null;
1113 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1114 if (!NT_STATUS_IS_OK(status)) {
1115 return dcesrv_bind_nak(call, 0);
1118 if (auth->auth_finished) {
1119 return dcesrv_auth_reply(call);
1122 subreq = gensec_update_send(call, call->event_ctx,
1123 auth->gensec_security,
1124 call->in_auth_info.credentials);
1125 if (subreq == NULL) {
1126 return NT_STATUS_NO_MEMORY;
1128 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1130 return dcesrv_conn_auth_wait_setup(conn);
1133 static void dcesrv_bind_done(struct tevent_req *subreq)
1135 struct dcesrv_call_state *call =
1136 tevent_req_callback_data(subreq,
1137 struct dcesrv_call_state);
1138 struct dcesrv_connection *conn = call->conn;
1139 NTSTATUS status;
1141 status = gensec_update_recv(subreq, call,
1142 &call->out_auth_info->credentials);
1143 TALLOC_FREE(subreq);
1145 status = dcesrv_auth_complete(call, status);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 status = dcesrv_bind_nak(call, 0);
1148 dcesrv_conn_auth_wait_finished(conn, status);
1149 return;
1152 status = dcesrv_auth_reply(call);
1153 dcesrv_conn_auth_wait_finished(conn, status);
1154 return;
1157 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1159 struct ncacn_packet *pkt = &call->ack_pkt;
1160 struct data_blob_list_item *rep = NULL;
1161 NTSTATUS status;
1163 rep = talloc_zero(call, struct data_blob_list_item);
1164 if (!rep) {
1165 return NT_STATUS_NO_MEMORY;
1168 status = ncacn_push_auth(&rep->blob, call, pkt,
1169 call->out_auth_info);
1170 if (!NT_STATUS_IS_OK(status)) {
1171 return status;
1174 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1176 DLIST_ADD_END(call->replies, rep);
1177 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1179 if (call->conn->call_list && call->conn->call_list->replies) {
1180 if (call->conn->transport.report_output_data) {
1181 call->conn->transport.report_output_data(call->conn);
1185 return NT_STATUS_OK;
1190 handle a auth3 request
1192 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1194 struct dcesrv_auth *auth = &call->conn->auth_state;
1195 NTSTATUS status;
1197 if (!call->conn->allow_auth3) {
1198 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1201 if (call->conn->auth_state.auth_finished) {
1202 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1205 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1206 DCERPC_PKT_AUTH3,
1207 call->pkt.u.auth3.auth_info.length,
1208 0, /* required flags */
1209 DCERPC_PFC_FLAG_FIRST |
1210 DCERPC_PFC_FLAG_LAST |
1211 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1212 0x08 | /* this is not defined, but should be ignored */
1213 DCERPC_PFC_FLAG_CONC_MPX |
1214 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1215 DCERPC_PFC_FLAG_MAYBE |
1216 DCERPC_PFC_FLAG_OBJECT_UUID);
1217 if (!NT_STATUS_IS_OK(status)) {
1218 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1221 /* handle the auth3 in the auth code */
1222 if (!dcesrv_auth_prepare_auth3(call)) {
1224 * we don't send a reply to a auth3 request,
1225 * except by a fault.
1227 * In anycase we mark the connection as
1228 * invalid.
1230 call->conn->auth_state.auth_invalid = true;
1231 if (call->fault_code != 0) {
1232 return dcesrv_fault_disconnect(call, call->fault_code);
1234 TALLOC_FREE(call);
1235 return NT_STATUS_OK;
1238 status = gensec_update_ev(auth->gensec_security,
1239 call, call->event_ctx,
1240 call->in_auth_info.credentials,
1241 &call->out_auth_info->credentials);
1243 status = dcesrv_auth_complete(call, status);
1244 if (!NT_STATUS_IS_OK(status)) {
1246 * we don't send a reply to a auth3 request,
1247 * except by a fault.
1249 * In anycase we mark the connection as
1250 * invalid.
1252 call->conn->auth_state.auth_invalid = true;
1253 if (call->fault_code != 0) {
1254 return dcesrv_fault_disconnect(call, call->fault_code);
1256 TALLOC_FREE(call);
1257 return NT_STATUS_OK;
1261 * we don't send a reply to a auth3 request.
1263 TALLOC_FREE(call);
1264 return NT_STATUS_OK;
1268 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1269 const struct dcerpc_bind *b,
1270 const struct dcerpc_ctx_list *ctx,
1271 struct dcerpc_ack_ctx *ack,
1272 bool validate_only,
1273 const struct ndr_syntax_id *supported_transfer)
1275 uint32_t if_version;
1276 struct dcesrv_connection_context *context;
1277 const struct dcesrv_interface *iface;
1278 struct GUID uuid;
1279 NTSTATUS status;
1280 const struct ndr_syntax_id *selected_transfer = NULL;
1281 size_t i;
1282 bool ok;
1284 if (b == NULL) {
1285 return NT_STATUS_INTERNAL_ERROR;
1287 if (ctx == NULL) {
1288 return NT_STATUS_INTERNAL_ERROR;
1290 if (ctx->num_transfer_syntaxes < 1) {
1291 return NT_STATUS_INTERNAL_ERROR;
1293 if (ack == NULL) {
1294 return NT_STATUS_INTERNAL_ERROR;
1296 if (supported_transfer == NULL) {
1297 return NT_STATUS_INTERNAL_ERROR;
1300 switch (ack->result) {
1301 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1302 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1304 * We is already completed.
1306 return NT_STATUS_OK;
1307 default:
1308 break;
1311 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1312 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1314 if_version = ctx->abstract_syntax.if_version;
1315 uuid = ctx->abstract_syntax.uuid;
1317 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1318 if (iface == NULL) {
1319 char *uuid_str = GUID_string(call, &uuid);
1320 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1321 talloc_free(uuid_str);
1323 * We report this only via ack->result
1325 return NT_STATUS_OK;
1328 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1329 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1331 if (validate_only) {
1333 * We report this only via ack->result
1335 return NT_STATUS_OK;
1338 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1340 * we only do NDR encoded dcerpc for now.
1342 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1343 supported_transfer);
1344 if (ok) {
1345 selected_transfer = supported_transfer;
1346 break;
1350 context = dcesrv_find_context(call->conn, ctx->context_id);
1351 if (context != NULL) {
1352 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1353 &ctx->abstract_syntax);
1354 if (!ok) {
1355 return NT_STATUS_RPC_PROTOCOL_ERROR;
1358 if (selected_transfer != NULL) {
1359 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1360 selected_transfer);
1361 if (!ok) {
1362 return NT_STATUS_RPC_PROTOCOL_ERROR;
1365 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1366 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1367 ack->syntax = context->transfer_syntax;
1371 * We report this only via ack->result
1373 return NT_STATUS_OK;
1376 if (selected_transfer == NULL) {
1378 * We report this only via ack->result
1380 return NT_STATUS_OK;
1383 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1384 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1386 /* add this context to the list of available context_ids */
1387 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1388 if (context == NULL) {
1389 return NT_STATUS_NO_MEMORY;
1391 context->conn = call->conn;
1392 context->context_id = ctx->context_id;
1393 context->iface = iface;
1394 context->transfer_syntax = *selected_transfer;
1395 context->private_data = NULL;
1396 DLIST_ADD(call->conn->contexts, context);
1397 call->context = context;
1398 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1400 dcesrv_prepare_context_auth(call);
1403 * Multiplex is supported by default
1405 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1407 status = iface->bind(call, iface, if_version);
1408 call->context = NULL;
1409 if (!NT_STATUS_IS_OK(status)) {
1410 /* we don't want to trigger the iface->unbind() hook */
1411 context->iface = NULL;
1412 talloc_free(context);
1414 * We report this only via ack->result
1416 return NT_STATUS_OK;
1419 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1420 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1421 ack->syntax = context->transfer_syntax;
1422 return NT_STATUS_OK;
1425 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1426 const struct dcerpc_bind *b,
1427 struct dcerpc_ack_ctx *ack_ctx_list)
1429 NTSTATUS status;
1430 size_t i;
1431 bool validate_only = false;
1432 bool preferred_ndr32;
1435 * Try to negotiate one new presentation context,
1436 * using our preferred transfer syntax.
1438 for (i = 0; i < b->num_contexts; i++) {
1439 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1440 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1442 status = dcesrv_check_or_create_context(call, b, c, a,
1443 validate_only,
1444 call->conn->preferred_transfer);
1445 if (!NT_STATUS_IS_OK(status)) {
1446 return status;
1449 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1451 * We managed to negotiate one context.
1453 * => we're done.
1455 validate_only = true;
1459 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1460 call->conn->preferred_transfer);
1461 if (preferred_ndr32) {
1463 * We're done.
1465 return NT_STATUS_OK;
1469 * Try to negotiate one new presentation context,
1470 * using NDR 32 as fallback.
1472 for (i = 0; i < b->num_contexts; i++) {
1473 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1474 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1476 status = dcesrv_check_or_create_context(call, b, c, a,
1477 validate_only,
1478 &ndr_transfer_syntax_ndr);
1479 if (!NT_STATUS_IS_OK(status)) {
1480 return status;
1483 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1485 * We managed to negotiate one context.
1487 * => we're done.
1489 validate_only = true;
1493 return NT_STATUS_OK;
1497 handle a alter context request
1499 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1501 NTSTATUS status;
1502 bool auth_ok = false;
1503 struct ncacn_packet *pkt = &call->ack_pkt;
1504 uint32_t extra_flags = 0;
1505 struct dcesrv_auth *auth = &call->conn->auth_state;
1506 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1507 size_t i;
1509 if (!call->conn->allow_alter) {
1510 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1513 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1514 DCERPC_PKT_ALTER,
1515 call->pkt.u.alter.auth_info.length,
1516 0, /* required flags */
1517 DCERPC_PFC_FLAG_FIRST |
1518 DCERPC_PFC_FLAG_LAST |
1519 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1520 0x08 | /* this is not defined, but should be ignored */
1521 DCERPC_PFC_FLAG_CONC_MPX |
1522 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1523 DCERPC_PFC_FLAG_MAYBE |
1524 DCERPC_PFC_FLAG_OBJECT_UUID);
1525 if (!NT_STATUS_IS_OK(status)) {
1526 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1529 auth_ok = dcesrv_auth_alter(call);
1530 if (!auth_ok) {
1531 if (call->fault_code != 0) {
1532 return dcesrv_fault_disconnect(call, call->fault_code);
1536 if (call->pkt.u.alter.num_contexts < 1) {
1537 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1540 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1541 call->pkt.u.alter.num_contexts);
1542 if (ack_ctx_list == NULL) {
1543 return NT_STATUS_NO_MEMORY;
1547 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1548 * dcesrv_check_or_create_context()) and do some protocol validation
1549 * and set sane defaults.
1551 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1552 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1553 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1555 if (c->num_transfer_syntaxes == 0) {
1556 return dcesrv_fault_disconnect(call,
1557 DCERPC_NCA_S_PROTO_ERROR);
1560 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1561 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1565 * Try to negotiate one new presentation context.
1567 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1568 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1569 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1571 if (!NT_STATUS_IS_OK(status)) {
1572 return status;
1575 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1576 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1577 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1578 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1581 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1582 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1585 /* handle any authentication that is being requested */
1586 if (!auth_ok) {
1587 if (call->in_auth_info.auth_type !=
1588 call->conn->auth_state.auth_type)
1590 return dcesrv_fault_disconnect(call,
1591 DCERPC_FAULT_SEC_PKG_ERROR);
1593 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1596 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1597 pkt->auth_length = 0;
1598 pkt->call_id = call->pkt.call_id;
1599 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1600 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1601 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1602 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1603 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1604 pkt->u.alter_resp.secondary_address = "";
1605 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1606 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1607 pkt->u.alter_resp.auth_info = data_blob_null;
1609 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1614 if (auth->auth_finished) {
1615 return dcesrv_auth_reply(call);
1618 status = gensec_update_ev(auth->gensec_security,
1619 call, call->event_ctx,
1620 call->in_auth_info.credentials,
1621 &call->out_auth_info->credentials);
1623 status = dcesrv_auth_complete(call, status);
1624 if (!NT_STATUS_IS_OK(status)) {
1625 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1628 return dcesrv_auth_reply(call);
1632 possibly save the call for inspection with ndrdump
1634 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1636 #ifdef DEVELOPER
1637 char *fname;
1638 const char *dump_dir;
1639 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1640 if (!dump_dir) {
1641 return;
1643 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1644 dump_dir,
1645 call->context->iface->name,
1646 call->pkt.u.request.opnum,
1647 why);
1648 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1649 DEBUG(0,("RPC SAVED %s\n", fname));
1651 talloc_free(fname);
1652 #endif
1655 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1657 TALLOC_CTX *frame = talloc_stackframe();
1658 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1659 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1660 const struct dcerpc_sec_vt_pcontext pcontext = {
1661 .abstract_syntax = call->context->iface->syntax_id,
1662 .transfer_syntax = call->context->transfer_syntax,
1664 const struct dcerpc_sec_vt_header2 header2 =
1665 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1666 enum ndr_err_code ndr_err;
1667 struct dcerpc_sec_verification_trailer *vt = NULL;
1668 NTSTATUS status = NT_STATUS_OK;
1669 bool ok;
1671 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1673 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1674 frame, &vt);
1675 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1676 status = ndr_map_error2ntstatus(ndr_err);
1677 goto done;
1680 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1681 &pcontext, &header2);
1682 if (!ok) {
1683 status = NT_STATUS_ACCESS_DENIED;
1684 goto done;
1686 done:
1687 TALLOC_FREE(frame);
1688 return status;
1692 handle a dcerpc request packet
1694 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1696 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1697 enum dcerpc_transport_t transport =
1698 dcerpc_binding_get_transport(endpoint->ep_description);
1699 struct ndr_pull *pull;
1700 NTSTATUS status;
1702 if (!call->conn->allow_request) {
1703 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1706 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1707 if (call->conn->auth_state.gensec_security &&
1708 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1709 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1712 if (call->context == NULL) {
1713 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1714 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1717 switch (call->conn->auth_state.auth_level) {
1718 case DCERPC_AUTH_LEVEL_NONE:
1719 case DCERPC_AUTH_LEVEL_PACKET:
1720 case DCERPC_AUTH_LEVEL_INTEGRITY:
1721 case DCERPC_AUTH_LEVEL_PRIVACY:
1722 break;
1723 default:
1724 if (!call->context->allow_connect) {
1725 char *addr;
1727 addr = tsocket_address_string(call->conn->remote_address,
1728 call);
1730 DEBUG(2, ("%s: restrict auth_level_connect access "
1731 "to [%s] with auth[type=0x%x,level=0x%x] "
1732 "on [%s] from [%s]\n",
1733 __func__, call->context->iface->name,
1734 call->conn->auth_state.auth_type,
1735 call->conn->auth_state.auth_level,
1736 derpc_transport_string_by_transport(transport),
1737 addr));
1738 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1740 break;
1743 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1744 char *addr;
1746 addr = tsocket_address_string(call->conn->remote_address, call);
1748 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1749 "to [%s] with auth[type=0x%x,level=0x%x] "
1750 "on [%s] from [%s]\n",
1751 __func__,
1752 call->context->min_auth_level,
1753 call->context->iface->name,
1754 call->conn->auth_state.auth_type,
1755 call->conn->auth_state.auth_level,
1756 derpc_transport_string_by_transport(transport),
1757 addr));
1758 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1761 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1762 NT_STATUS_HAVE_NO_MEMORY(pull);
1764 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1766 call->ndr_pull = pull;
1768 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1769 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1772 status = dcesrv_check_verification_trailer(call);
1773 if (!NT_STATUS_IS_OK(status)) {
1774 uint32_t faultcode = DCERPC_FAULT_OTHER;
1775 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1776 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1778 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1779 nt_errstr(status)));
1780 return dcesrv_fault(call, faultcode);
1783 /* unravel the NDR for the packet */
1784 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1785 if (!NT_STATUS_IS_OK(status)) {
1786 uint8_t extra_flags = 0;
1787 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1788 /* we got an unknown call */
1789 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1790 call->pkt.u.request.opnum,
1791 call->context->iface->name));
1792 dcesrv_save_call(call, "unknown");
1793 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1794 } else {
1795 dcesrv_save_call(call, "pullfail");
1797 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1800 if (pull->offset != pull->data_size) {
1801 dcesrv_save_call(call, "extrabytes");
1802 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1803 pull->data_size - pull->offset));
1806 /* call the dispatch function */
1807 status = call->context->iface->dispatch(call, call, call->r);
1808 if (!NT_STATUS_IS_OK(status)) {
1809 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1810 call->context->iface->name,
1811 call->pkt.u.request.opnum,
1812 dcerpc_errstr(pull, call->fault_code)));
1813 return dcesrv_fault(call, call->fault_code);
1816 /* add the call to the pending list */
1817 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1819 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1820 return NT_STATUS_OK;
1823 return dcesrv_reply(call);
1828 remove the call from the right list when freed
1830 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1832 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1833 return 0;
1836 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1838 return conn->local_address;
1841 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1843 return conn->remote_address;
1847 process some input to a dcerpc endpoint server.
1849 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1850 struct ncacn_packet *pkt,
1851 DATA_BLOB blob)
1853 NTSTATUS status;
1854 struct dcesrv_call_state *call;
1855 struct dcesrv_call_state *existing = NULL;
1857 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1858 if (!call) {
1859 data_blob_free(&blob);
1860 talloc_free(pkt);
1861 return NT_STATUS_NO_MEMORY;
1863 call->conn = dce_conn;
1864 call->event_ctx = dce_conn->event_ctx;
1865 call->msg_ctx = dce_conn->msg_ctx;
1866 call->state_flags = call->conn->state_flags;
1867 call->time = timeval_current();
1868 call->list = DCESRV_LIST_NONE;
1870 talloc_steal(call, pkt);
1871 talloc_steal(call, blob.data);
1872 call->pkt = *pkt;
1874 talloc_set_destructor(call, dcesrv_call_dequeue);
1876 if (call->conn->allow_bind) {
1878 * Only one bind is possible per connection
1880 call->conn->allow_bind = false;
1881 return dcesrv_bind(call);
1884 /* we have to check the signing here, before combining the
1885 pdus */
1886 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1887 if (!call->conn->allow_request) {
1888 return dcesrv_fault_disconnect(call,
1889 DCERPC_NCA_S_PROTO_ERROR);
1892 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1893 DCERPC_PKT_REQUEST,
1894 call->pkt.u.request.stub_and_verifier.length,
1895 0, /* required_flags */
1896 DCERPC_PFC_FLAG_FIRST |
1897 DCERPC_PFC_FLAG_LAST |
1898 DCERPC_PFC_FLAG_PENDING_CANCEL |
1899 0x08 | /* this is not defined, but should be ignored */
1900 DCERPC_PFC_FLAG_CONC_MPX |
1901 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1902 DCERPC_PFC_FLAG_MAYBE |
1903 DCERPC_PFC_FLAG_OBJECT_UUID);
1904 if (!NT_STATUS_IS_OK(status)) {
1905 return dcesrv_fault_disconnect(call,
1906 DCERPC_NCA_S_PROTO_ERROR);
1909 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1911 * We don't use dcesrv_fault_disconnect()
1912 * here, because we don't want to set
1913 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1915 * Note that we don't check against the negotiated
1916 * max_recv_frag, but a hard coded value.
1918 dcesrv_call_disconnect_after(call,
1919 "dcesrv_auth_request - frag_length too large");
1920 return dcesrv_fault(call,
1921 DCERPC_NCA_S_PROTO_ERROR);
1924 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1925 if (dce_conn->pending_call_list != NULL) {
1927 * concurrent requests are only allowed
1928 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1930 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1931 dcesrv_call_disconnect_after(call,
1932 "dcesrv_auth_request - "
1933 "existing pending call without CONN_MPX");
1934 return dcesrv_fault(call,
1935 DCERPC_NCA_S_PROTO_ERROR);
1938 /* only one request is possible in the fragmented list */
1939 if (dce_conn->incoming_fragmented_call_list != NULL) {
1940 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1942 * Without DCERPC_PFC_FLAG_CONC_MPX
1943 * we need to return the FAULT on the
1944 * already existing call.
1946 * This is important to get the
1947 * call_id and context_id right.
1949 TALLOC_FREE(call);
1950 call = dce_conn->incoming_fragmented_call_list;
1952 dcesrv_call_disconnect_after(call,
1953 "dcesrv_auth_request - "
1954 "existing fragmented call");
1955 return dcesrv_fault(call,
1956 DCERPC_NCA_S_PROTO_ERROR);
1958 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1959 return dcesrv_fault_disconnect(call,
1960 DCERPC_FAULT_NO_CALL_ACTIVE);
1962 call->context = dcesrv_find_context(call->conn,
1963 call->pkt.u.request.context_id);
1964 if (call->context == NULL) {
1965 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1966 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1968 } else {
1969 const struct dcerpc_request *nr = &call->pkt.u.request;
1970 const struct dcerpc_request *er = NULL;
1971 int cmp;
1973 existing = dcesrv_find_fragmented_call(dce_conn,
1974 call->pkt.call_id);
1975 if (existing == NULL) {
1976 dcesrv_call_disconnect_after(call,
1977 "dcesrv_auth_request - "
1978 "no existing fragmented call");
1979 return dcesrv_fault(call,
1980 DCERPC_NCA_S_PROTO_ERROR);
1982 er = &existing->pkt.u.request;
1984 if (call->pkt.ptype != existing->pkt.ptype) {
1985 /* trying to play silly buggers are we? */
1986 return dcesrv_fault_disconnect(existing,
1987 DCERPC_NCA_S_PROTO_ERROR);
1989 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1990 sizeof(pkt->drep));
1991 if (cmp != 0) {
1992 return dcesrv_fault_disconnect(existing,
1993 DCERPC_NCA_S_PROTO_ERROR);
1995 if (nr->context_id != er->context_id) {
1996 return dcesrv_fault_disconnect(existing,
1997 DCERPC_NCA_S_PROTO_ERROR);
1999 if (nr->opnum != er->opnum) {
2000 return dcesrv_fault_disconnect(existing,
2001 DCERPC_NCA_S_PROTO_ERROR);
2006 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2007 bool ok;
2008 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2010 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2011 payload_offset += 16;
2014 ok = dcesrv_auth_pkt_pull(call, &blob,
2015 0, /* required_flags */
2016 DCERPC_PFC_FLAG_FIRST |
2017 DCERPC_PFC_FLAG_LAST |
2018 DCERPC_PFC_FLAG_PENDING_CANCEL |
2019 0x08 | /* this is not defined, but should be ignored */
2020 DCERPC_PFC_FLAG_CONC_MPX |
2021 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2022 DCERPC_PFC_FLAG_MAYBE |
2023 DCERPC_PFC_FLAG_OBJECT_UUID,
2024 payload_offset,
2025 &call->pkt.u.request.stub_and_verifier);
2026 if (!ok) {
2028 * We don't use dcesrv_fault_disconnect()
2029 * here, because we don't want to set
2030 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2032 dcesrv_call_disconnect_after(call,
2033 "dcesrv_auth_request - failed");
2034 if (call->fault_code == 0) {
2035 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2037 return dcesrv_fault(call, call->fault_code);
2041 /* see if this is a continued packet */
2042 if (existing != NULL) {
2043 struct dcerpc_request *er = &existing->pkt.u.request;
2044 const struct dcerpc_request *nr = &call->pkt.u.request;
2045 size_t available;
2046 size_t alloc_size;
2047 size_t alloc_hint;
2050 * Up to 4 MByte are allowed by all fragments
2052 available = dce_conn->max_total_request_size;
2053 if (er->stub_and_verifier.length > available) {
2054 dcesrv_call_disconnect_after(existing,
2055 "dcesrv_auth_request - existing payload too large");
2056 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2058 available -= er->stub_and_verifier.length;
2059 if (nr->alloc_hint > available) {
2060 dcesrv_call_disconnect_after(existing,
2061 "dcesrv_auth_request - alloc hint too large");
2062 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2064 if (nr->stub_and_verifier.length > available) {
2065 dcesrv_call_disconnect_after(existing,
2066 "dcesrv_auth_request - new payload too large");
2067 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2069 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2070 /* allocate at least 1 byte */
2071 alloc_hint = MAX(alloc_hint, 1);
2072 alloc_size = er->stub_and_verifier.length +
2073 nr->stub_and_verifier.length;
2074 alloc_size = MAX(alloc_size, alloc_hint);
2076 er->stub_and_verifier.data =
2077 talloc_realloc(existing,
2078 er->stub_and_verifier.data,
2079 uint8_t, alloc_size);
2080 if (er->stub_and_verifier.data == NULL) {
2081 TALLOC_FREE(call);
2082 return dcesrv_fault_with_flags(existing,
2083 DCERPC_FAULT_OUT_OF_RESOURCES,
2084 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2086 memcpy(er->stub_and_verifier.data +
2087 er->stub_and_verifier.length,
2088 nr->stub_and_verifier.data,
2089 nr->stub_and_verifier.length);
2090 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2092 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2094 TALLOC_FREE(call);
2095 call = existing;
2098 /* this may not be the last pdu in the chain - if its isn't then
2099 just put it on the incoming_fragmented_call_list and wait for the rest */
2100 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2101 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2103 * Up to 4 MByte are allowed by all fragments
2105 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2106 dcesrv_call_disconnect_after(call,
2107 "dcesrv_auth_request - initial alloc hint too large");
2108 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2110 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2111 return NT_STATUS_OK;
2114 /* This removes any fragments we may have had stashed away */
2115 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2117 switch (call->pkt.ptype) {
2118 case DCERPC_PKT_BIND:
2119 status = dcesrv_bind_nak(call,
2120 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2121 break;
2122 case DCERPC_PKT_AUTH3:
2123 status = dcesrv_auth3(call);
2124 break;
2125 case DCERPC_PKT_ALTER:
2126 status = dcesrv_alter(call);
2127 break;
2128 case DCERPC_PKT_REQUEST:
2129 status = dcesrv_request(call);
2130 break;
2131 case DCERPC_PKT_CO_CANCEL:
2132 case DCERPC_PKT_ORPHANED:
2134 * Window just ignores CO_CANCEL and ORPHANED,
2135 * so we do...
2137 status = NT_STATUS_OK;
2138 TALLOC_FREE(call);
2139 break;
2140 case DCERPC_PKT_BIND_ACK:
2141 case DCERPC_PKT_BIND_NAK:
2142 case DCERPC_PKT_ALTER_RESP:
2143 case DCERPC_PKT_RESPONSE:
2144 case DCERPC_PKT_FAULT:
2145 case DCERPC_PKT_SHUTDOWN:
2146 default:
2147 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2148 break;
2151 /* if we are going to be sending a reply then add
2152 it to the list of pending calls. We add it to the end to keep the call
2153 list in the order we will answer */
2154 if (!NT_STATUS_IS_OK(status)) {
2155 talloc_free(call);
2158 return status;
2161 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2162 struct loadparm_context *lp_ctx,
2163 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2165 NTSTATUS status;
2166 struct dcesrv_context *dce_ctx;
2167 int i;
2169 if (!endpoint_servers) {
2170 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2171 return NT_STATUS_INTERNAL_ERROR;
2174 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2175 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2177 if (uid_wrapper_enabled()) {
2178 setenv("UID_WRAPPER_MYUID", "1", 1);
2180 dce_ctx->initial_euid = geteuid();
2181 if (uid_wrapper_enabled()) {
2182 unsetenv("UID_WRAPPER_MYUID");
2185 dce_ctx->endpoint_list = NULL;
2186 dce_ctx->lp_ctx = lp_ctx;
2187 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2188 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2189 dce_ctx->broken_connections = NULL;
2191 for (i=0;endpoint_servers[i];i++) {
2192 const struct dcesrv_endpoint_server *ep_server;
2194 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2195 if (!ep_server) {
2196 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2197 return NT_STATUS_INTERNAL_ERROR;
2200 status = ep_server->init_server(dce_ctx, ep_server);
2201 if (!NT_STATUS_IS_OK(status)) {
2202 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2203 nt_errstr(status)));
2204 return status;
2208 *_dce_ctx = dce_ctx;
2209 return NT_STATUS_OK;
2212 /* the list of currently registered DCERPC endpoint servers.
2214 static struct ep_server {
2215 struct dcesrv_endpoint_server *ep_server;
2216 } *ep_servers = NULL;
2217 static int num_ep_servers;
2220 register a DCERPC endpoint server.
2222 The 'name' can be later used by other backends to find the operations
2223 structure for this backend.
2226 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2229 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2230 /* its already registered! */
2231 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2232 ep_server->name));
2233 return NT_STATUS_OBJECT_NAME_COLLISION;
2236 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2237 if (!ep_servers) {
2238 smb_panic("out of memory in dcerpc_register");
2241 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2242 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2244 num_ep_servers++;
2246 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2247 ep_server->name));
2249 return NT_STATUS_OK;
2253 return the operations structure for a named backend of the specified type
2255 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2257 int i;
2259 for (i=0;i<num_ep_servers;i++) {
2260 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2261 return ep_servers[i].ep_server;
2265 return NULL;
2268 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2270 static bool initialized;
2271 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2272 STATIC_dcerpc_server_MODULES_PROTO;
2273 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2274 init_module_fn *shared_init;
2276 if (initialized) {
2277 return;
2279 initialized = true;
2281 shared_init = load_samba_modules(NULL, "dcerpc_server");
2283 run_init_functions(NULL, static_init);
2284 run_init_functions(NULL, shared_init);
2286 talloc_free(shared_init);
2290 return the DCERPC module version, and the size of some critical types
2291 This can be used by endpoint server modules to either detect compilation errors, or provide
2292 multiple implementations for different smbd compilation options in one module
2294 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2296 static const struct dcesrv_critical_sizes critical_sizes = {
2297 DCERPC_MODULE_VERSION,
2298 sizeof(struct dcesrv_context),
2299 sizeof(struct dcesrv_endpoint),
2300 sizeof(struct dcesrv_endpoint_server),
2301 sizeof(struct dcesrv_interface),
2302 sizeof(struct dcesrv_if_list),
2303 sizeof(struct dcesrv_connection),
2304 sizeof(struct dcesrv_call_state),
2305 sizeof(struct dcesrv_auth),
2306 sizeof(struct dcesrv_handle)
2309 return &critical_sizes;
2312 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2314 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2315 struct stream_connection *srv_conn;
2316 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2317 struct stream_connection);
2319 dce_conn->wait_send = NULL;
2320 dce_conn->wait_recv = NULL;
2321 dce_conn->wait_private = NULL;
2323 dce_conn->allow_bind = false;
2324 dce_conn->allow_auth3 = false;
2325 dce_conn->allow_alter = false;
2326 dce_conn->allow_request = false;
2328 if (dce_conn->pending_call_list == NULL) {
2329 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2331 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2332 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2333 return;
2336 if (dce_conn->terminate != NULL) {
2337 return;
2340 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2341 reason));
2342 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2343 if (dce_conn->terminate == NULL) {
2344 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2346 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2349 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2351 struct dcesrv_connection *cur, *next;
2353 next = dce_ctx->broken_connections;
2354 while (next != NULL) {
2355 cur = next;
2356 next = cur->next;
2358 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2359 struct dcesrv_connection_context *context_cur, *context_next;
2361 context_next = cur->contexts;
2362 while (context_next != NULL) {
2363 context_cur = context_next;
2364 context_next = context_cur->next;
2366 dcesrv_connection_context_destructor(context_cur);
2370 dcesrv_terminate_connection(cur, cur->terminate);
2374 /* We need this include to be able to compile on some plateforms
2375 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2376 * correctly.
2377 * It has to be that deep because otherwise we have a conflict on
2378 * const struct dcesrv_interface declaration.
2379 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2380 * which conflict with the bind used before.
2382 #include "system/network.h"
2384 struct dcesrv_sock_reply_state {
2385 struct dcesrv_connection *dce_conn;
2386 struct dcesrv_call_state *call;
2387 struct iovec iov;
2390 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2391 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2393 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2395 struct dcesrv_call_state *call;
2397 call = dce_conn->call_list;
2398 if (!call || !call->replies) {
2399 return;
2402 while (call->replies) {
2403 struct data_blob_list_item *rep = call->replies;
2404 struct dcesrv_sock_reply_state *substate;
2405 struct tevent_req *subreq;
2407 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2408 if (!substate) {
2409 dcesrv_terminate_connection(dce_conn, "no memory");
2410 return;
2413 substate->dce_conn = dce_conn;
2414 substate->call = NULL;
2416 DLIST_REMOVE(call->replies, rep);
2418 if (call->replies == NULL && call->terminate_reason == NULL) {
2419 substate->call = call;
2422 substate->iov.iov_base = (void *) rep->blob.data;
2423 substate->iov.iov_len = rep->blob.length;
2425 subreq = tstream_writev_queue_send(substate,
2426 dce_conn->event_ctx,
2427 dce_conn->stream,
2428 dce_conn->send_queue,
2429 &substate->iov, 1);
2430 if (!subreq) {
2431 dcesrv_terminate_connection(dce_conn, "no memory");
2432 return;
2434 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2435 substate);
2438 if (call->terminate_reason != NULL) {
2439 struct tevent_req *subreq;
2441 subreq = tevent_queue_wait_send(call,
2442 dce_conn->event_ctx,
2443 dce_conn->send_queue);
2444 if (!subreq) {
2445 dcesrv_terminate_connection(dce_conn, __location__);
2446 return;
2448 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2449 call);
2452 DLIST_REMOVE(call->conn->call_list, call);
2453 call->list = DCESRV_LIST_NONE;
2456 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2458 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2459 struct dcesrv_sock_reply_state);
2460 int ret;
2461 int sys_errno;
2462 NTSTATUS status;
2463 struct dcesrv_call_state *call = substate->call;
2465 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2466 TALLOC_FREE(subreq);
2467 if (ret == -1) {
2468 status = map_nt_error_from_unix_common(sys_errno);
2469 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2470 return;
2473 talloc_free(substate);
2474 if (call) {
2475 talloc_free(call);
2479 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2481 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2483 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2484 struct dcesrv_call_state);
2485 bool ok;
2486 struct timeval tv;
2488 /* make sure we stop send queue before removing subreq */
2489 tevent_queue_stop(call->conn->send_queue);
2491 ok = tevent_queue_wait_recv(subreq);
2492 TALLOC_FREE(subreq);
2493 if (!ok) {
2494 dcesrv_terminate_connection(call->conn, __location__);
2495 return;
2498 /* disconnect after 200 usecs */
2499 tv = timeval_current_ofs_usec(200);
2500 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2501 if (subreq == NULL) {
2502 dcesrv_terminate_connection(call->conn, __location__);
2503 return;
2505 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2506 call);
2509 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2511 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2512 struct dcesrv_call_state);
2513 bool ok;
2515 ok = tevent_wakeup_recv(subreq);
2516 TALLOC_FREE(subreq);
2517 if (!ok) {
2518 dcesrv_terminate_connection(call->conn, __location__);
2519 return;
2522 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2525 struct dcesrv_socket_context {
2526 const struct dcesrv_endpoint *endpoint;
2527 struct dcesrv_context *dcesrv_ctx;
2531 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2533 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2535 NTSTATUS status;
2536 struct dcesrv_socket_context *dcesrv_sock =
2537 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2538 enum dcerpc_transport_t transport =
2539 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2540 struct dcesrv_connection *dcesrv_conn = NULL;
2541 int ret;
2542 struct tevent_req *subreq;
2543 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2545 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2547 if (!srv_conn->session_info) {
2548 status = auth_anonymous_session_info(srv_conn,
2549 lp_ctx,
2550 &srv_conn->session_info);
2551 if (!NT_STATUS_IS_OK(status)) {
2552 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2553 nt_errstr(status)));
2554 stream_terminate_connection(srv_conn, nt_errstr(status));
2555 return;
2560 * This fills in dcesrv_conn->endpoint with the endpoint
2561 * associated with the socket. From this point on we know
2562 * which (group of) services we are handling, but not the
2563 * specific interface.
2566 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2567 srv_conn,
2568 dcesrv_sock->endpoint,
2569 srv_conn->session_info,
2570 srv_conn->event.ctx,
2571 srv_conn->msg_ctx,
2572 srv_conn->server_id,
2573 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2574 &dcesrv_conn);
2575 if (!NT_STATUS_IS_OK(status)) {
2576 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2577 nt_errstr(status)));
2578 stream_terminate_connection(srv_conn, nt_errstr(status));
2579 return;
2582 dcesrv_conn->transport.private_data = srv_conn;
2583 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2585 TALLOC_FREE(srv_conn->event.fde);
2587 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2588 if (!dcesrv_conn->send_queue) {
2589 status = NT_STATUS_NO_MEMORY;
2590 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2591 nt_errstr(status)));
2592 stream_terminate_connection(srv_conn, nt_errstr(status));
2593 return;
2596 if (transport == NCACN_NP) {
2597 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2598 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2599 &srv_conn->tstream);
2600 } else {
2601 ret = tstream_bsd_existing_socket(dcesrv_conn,
2602 socket_get_fd(srv_conn->socket),
2603 &dcesrv_conn->stream);
2604 if (ret == -1) {
2605 status = map_nt_error_from_unix_common(errno);
2606 DEBUG(0, ("dcesrv_sock_accept: "
2607 "failed to setup tstream: %s\n",
2608 nt_errstr(status)));
2609 stream_terminate_connection(srv_conn, nt_errstr(status));
2610 return;
2612 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2615 dcesrv_conn->local_address = srv_conn->local_address;
2616 dcesrv_conn->remote_address = srv_conn->remote_address;
2618 if (transport == NCALRPC) {
2619 uid_t uid;
2620 gid_t gid;
2621 int sock_fd;
2623 sock_fd = socket_get_fd(srv_conn->socket);
2624 if (sock_fd == -1) {
2625 stream_terminate_connection(
2626 srv_conn, "socket_get_fd failed\n");
2627 return;
2630 ret = getpeereid(sock_fd, &uid, &gid);
2631 if (ret == -1) {
2632 status = map_nt_error_from_unix_common(errno);
2633 DEBUG(0, ("dcesrv_sock_accept: "
2634 "getpeereid() failed for NCALRPC: %s\n",
2635 nt_errstr(status)));
2636 stream_terminate_connection(srv_conn, nt_errstr(status));
2637 return;
2639 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2640 struct tsocket_address *r = NULL;
2642 ret = tsocket_address_unix_from_path(dcesrv_conn,
2643 "/root/ncalrpc_as_system",
2644 &r);
2645 if (ret == -1) {
2646 status = map_nt_error_from_unix_common(errno);
2647 DEBUG(0, ("dcesrv_sock_accept: "
2648 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2649 nt_errstr(status)));
2650 stream_terminate_connection(srv_conn, nt_errstr(status));
2651 return;
2653 dcesrv_conn->remote_address = r;
2657 srv_conn->private_data = dcesrv_conn;
2659 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2661 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2662 dcesrv_conn->event_ctx,
2663 dcesrv_conn->stream);
2664 if (!subreq) {
2665 status = NT_STATUS_NO_MEMORY;
2666 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2667 nt_errstr(status)));
2668 stream_terminate_connection(srv_conn, nt_errstr(status));
2669 return;
2671 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2673 return;
2676 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2678 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2680 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2681 struct dcesrv_connection);
2682 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2683 struct ncacn_packet *pkt;
2684 DATA_BLOB buffer;
2685 NTSTATUS status;
2687 if (dce_conn->terminate) {
2689 * if the current connection is broken
2690 * we need to clean it up before any other connection
2692 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2693 dcesrv_cleanup_broken_connections(dce_ctx);
2694 return;
2697 dcesrv_cleanup_broken_connections(dce_ctx);
2699 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2700 &pkt, &buffer);
2701 TALLOC_FREE(subreq);
2702 if (!NT_STATUS_IS_OK(status)) {
2703 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2704 return;
2707 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2708 if (!NT_STATUS_IS_OK(status)) {
2709 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2710 return;
2714 * This is used to block the connection during
2715 * pending authentication.
2717 if (dce_conn->wait_send != NULL) {
2718 subreq = dce_conn->wait_send(dce_conn,
2719 dce_conn->event_ctx,
2720 dce_conn->wait_private);
2721 if (!subreq) {
2722 status = NT_STATUS_NO_MEMORY;
2723 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2724 return;
2726 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2727 return;
2730 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2731 dce_conn->event_ctx,
2732 dce_conn->stream);
2733 if (!subreq) {
2734 status = NT_STATUS_NO_MEMORY;
2735 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2736 return;
2738 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2741 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2743 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2744 struct dcesrv_connection);
2745 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2746 NTSTATUS status;
2748 if (dce_conn->terminate) {
2750 * if the current connection is broken
2751 * we need to clean it up before any other connection
2753 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2754 dcesrv_cleanup_broken_connections(dce_ctx);
2755 return;
2758 dcesrv_cleanup_broken_connections(dce_ctx);
2760 status = dce_conn->wait_recv(subreq);
2761 dce_conn->wait_send = NULL;
2762 dce_conn->wait_recv = NULL;
2763 dce_conn->wait_private = NULL;
2764 TALLOC_FREE(subreq);
2765 if (!NT_STATUS_IS_OK(status)) {
2766 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2767 return;
2770 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2771 dce_conn->event_ctx,
2772 dce_conn->stream);
2773 if (!subreq) {
2774 status = NT_STATUS_NO_MEMORY;
2775 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2776 return;
2778 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2781 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2783 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2784 struct dcesrv_connection);
2785 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2788 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2790 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2791 struct dcesrv_connection);
2792 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2796 static const struct stream_server_ops dcesrv_stream_ops = {
2797 .name = "rpc",
2798 .accept_connection = dcesrv_sock_accept,
2799 .recv_handler = dcesrv_sock_recv,
2800 .send_handler = dcesrv_sock_send,
2803 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2804 struct loadparm_context *lp_ctx,
2805 struct dcesrv_endpoint *e,
2806 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2808 struct dcesrv_socket_context *dcesrv_sock;
2809 uint16_t port = 1;
2810 NTSTATUS status;
2811 const char *endpoint;
2813 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2814 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2816 /* remember the endpoint of this socket */
2817 dcesrv_sock->endpoint = e;
2818 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2820 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2822 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2823 model_ops, &dcesrv_stream_ops,
2824 "unix", endpoint, &port,
2825 lpcfg_socket_options(lp_ctx),
2826 dcesrv_sock);
2827 if (!NT_STATUS_IS_OK(status)) {
2828 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2829 endpoint, nt_errstr(status)));
2832 return status;
2835 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2836 struct loadparm_context *lp_ctx,
2837 struct dcesrv_endpoint *e,
2838 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2840 struct dcesrv_socket_context *dcesrv_sock;
2841 uint16_t port = 1;
2842 char *full_path;
2843 NTSTATUS status;
2844 const char *endpoint;
2846 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2848 if (endpoint == NULL) {
2850 * No identifier specified: use DEFAULT.
2852 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2853 * no endpoint and let the epmapper worry about it.
2855 endpoint = "DEFAULT";
2856 status = dcerpc_binding_set_string_option(e->ep_description,
2857 "endpoint",
2858 endpoint);
2859 if (!NT_STATUS_IS_OK(status)) {
2860 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2861 nt_errstr(status)));
2862 return status;
2866 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2867 endpoint);
2869 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2870 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2872 /* remember the endpoint of this socket */
2873 dcesrv_sock->endpoint = e;
2874 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2876 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2877 model_ops, &dcesrv_stream_ops,
2878 "unix", full_path, &port,
2879 lpcfg_socket_options(lp_ctx),
2880 dcesrv_sock);
2881 if (!NT_STATUS_IS_OK(status)) {
2882 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2883 endpoint, full_path, nt_errstr(status)));
2885 return status;
2888 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2889 struct loadparm_context *lp_ctx,
2890 struct dcesrv_endpoint *e,
2891 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2893 struct dcesrv_socket_context *dcesrv_sock;
2894 NTSTATUS status;
2895 const char *endpoint;
2897 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2898 if (endpoint == NULL) {
2899 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2900 return NT_STATUS_INVALID_PARAMETER;
2903 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2904 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2906 /* remember the endpoint of this socket */
2907 dcesrv_sock->endpoint = e;
2908 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2910 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2911 model_ops, &dcesrv_stream_ops,
2912 endpoint,
2913 dcesrv_sock);
2914 if (!NT_STATUS_IS_OK(status)) {
2915 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2916 endpoint, nt_errstr(status)));
2917 return status;
2920 return NT_STATUS_OK;
2924 add a socket address to the list of events, one event per dcerpc endpoint
2926 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2927 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2928 const char *address)
2930 struct dcesrv_socket_context *dcesrv_sock;
2931 uint16_t port = 0;
2932 NTSTATUS status;
2933 const char *endpoint;
2934 char port_str[6];
2936 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2937 if (endpoint != NULL) {
2938 port = atoi(endpoint);
2941 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2942 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2944 /* remember the endpoint of this socket */
2945 dcesrv_sock->endpoint = e;
2946 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2948 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2949 model_ops, &dcesrv_stream_ops,
2950 "ip", address, &port,
2951 lpcfg_socket_options(dce_ctx->lp_ctx),
2952 dcesrv_sock);
2953 if (!NT_STATUS_IS_OK(status)) {
2954 struct dcesrv_if_list *iface;
2955 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2956 address, port));
2957 for (iface = e->interface_list; iface; iface = iface->next) {
2958 DEBUGADD(0, ("%s ", iface->iface.name));
2960 DEBUGADD(0, ("failed - %s",
2961 nt_errstr(status)));
2962 return status;
2965 snprintf(port_str, sizeof(port_str), "%u", port);
2967 status = dcerpc_binding_set_string_option(e->ep_description,
2968 "endpoint", port_str);
2969 if (!NT_STATUS_IS_OK(status)) {
2970 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2971 port_str, nt_errstr(status)));
2972 return status;
2973 } else {
2974 struct dcesrv_if_list *iface;
2975 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2976 address, port_str));
2977 for (iface = e->interface_list; iface; iface = iface->next) {
2978 DEBUGADD(4, ("%s ", iface->iface.name));
2980 DEBUGADD(4, ("\n"));
2983 return NT_STATUS_OK;
2986 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2988 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2989 struct loadparm_context *lp_ctx,
2990 struct dcesrv_endpoint *e,
2991 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2993 NTSTATUS status;
2995 /* Add TCP/IP sockets */
2996 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2997 int num_interfaces;
2998 int i;
2999 struct interface *ifaces;
3001 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3003 num_interfaces = iface_list_count(ifaces);
3004 for(i = 0; i < num_interfaces; i++) {
3005 const char *address = iface_list_n_ip(ifaces, i);
3006 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
3007 NT_STATUS_NOT_OK_RETURN(status);
3009 } else {
3010 char **wcard;
3011 int i;
3012 int num_binds = 0;
3013 wcard = iface_list_wildcard(dce_ctx);
3014 NT_STATUS_HAVE_NO_MEMORY(wcard);
3015 for (i=0; wcard[i]; i++) {
3016 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
3017 if (NT_STATUS_IS_OK(status)) {
3018 num_binds++;
3021 talloc_free(wcard);
3022 if (num_binds == 0) {
3023 return NT_STATUS_INVALID_PARAMETER_MIX;
3027 return NT_STATUS_OK;
3030 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3031 struct loadparm_context *lp_ctx,
3032 struct dcesrv_endpoint *e,
3033 struct tevent_context *event_ctx,
3034 const struct model_ops *model_ops)
3036 enum dcerpc_transport_t transport =
3037 dcerpc_binding_get_transport(e->ep_description);
3039 switch (transport) {
3040 case NCACN_UNIX_STREAM:
3041 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3043 case NCALRPC:
3044 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3046 case NCACN_IP_TCP:
3047 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3049 case NCACN_NP:
3050 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
3052 default:
3053 return NT_STATUS_NOT_SUPPORTED;
3059 * retrieve credentials from a dce_call
3061 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3063 return dce_call->conn->auth_state.session_info->credentials;
3067 * returns true if this is an authenticated call
3069 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3071 enum security_user_level level;
3072 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3073 return level >= SECURITY_USER;
3077 * retrieve account_name for a dce_call
3079 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3081 return dce_call->context->conn->auth_state.session_info->info->account_name;