s4:rpc_server: remove useless TALLOC_FREE(call->context) from dcesrv_bind()
[Samba.git] / source4 / rpc_server / dcerpc_server.c
blob34de07171e6ec651e3b50c225e8267241153d545
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"
45 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
46 const struct dcerpc_bind *b,
47 struct dcerpc_ack_ctx *ack_ctx_list);
50 find an association group given a assoc_group_id
52 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
53 uint32_t id)
55 void *id_ptr;
57 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
58 if (id_ptr == NULL) {
59 return NULL;
61 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
65 take a reference to an existing association group
67 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
68 struct dcesrv_context *dce_ctx,
69 uint32_t id)
71 struct dcesrv_assoc_group *assoc_group;
73 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
74 if (assoc_group == NULL) {
75 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
76 return NULL;
78 return talloc_reference(mem_ctx, assoc_group);
81 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
83 int ret;
84 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
85 if (ret != 0) {
86 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
87 assoc_group->id));
89 return 0;
93 allocate a new association group
95 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
96 struct dcesrv_context *dce_ctx)
98 struct dcesrv_assoc_group *assoc_group;
99 int id;
101 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
102 if (assoc_group == NULL) {
103 return NULL;
106 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
107 if (id == -1) {
108 talloc_free(assoc_group);
109 DEBUG(0,(__location__ ": Out of association groups!\n"));
110 return NULL;
113 assoc_group->id = id;
114 assoc_group->dce_ctx = dce_ctx;
116 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
118 return assoc_group;
123 see if two endpoints match
125 static bool endpoints_match(const struct dcerpc_binding *ep1,
126 const struct dcerpc_binding *ep2)
128 enum dcerpc_transport_t t1;
129 enum dcerpc_transport_t t2;
130 const char *e1;
131 const char *e2;
133 t1 = dcerpc_binding_get_transport(ep1);
134 t2 = dcerpc_binding_get_transport(ep2);
136 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
137 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
139 if (t1 != t2) {
140 return false;
143 if (!e1 || !e2) {
144 return e1 == e2;
147 if (strcasecmp(e1, e2) != 0) {
148 return false;
151 return true;
155 find an endpoint in the dcesrv_context
157 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
158 const struct dcerpc_binding *ep_description)
160 struct dcesrv_endpoint *ep;
161 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
162 if (endpoints_match(ep->ep_description, ep_description)) {
163 return ep;
166 return NULL;
170 find a registered context_id from a bind or alter_context
172 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
173 uint16_t context_id)
175 struct dcesrv_connection_context *c;
176 for (c=conn->contexts;c;c=c->next) {
177 if (c->context_id == context_id) return c;
179 return NULL;
183 see if a uuid and if_version match to an interface
185 static bool interface_match(const struct dcesrv_interface *if1,
186 const struct dcesrv_interface *if2)
188 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
189 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
193 find the interface operations on any endpoint with this binding
195 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
196 struct dcerpc_binding *binding,
197 const struct dcesrv_interface *iface)
199 struct dcesrv_endpoint *ep;
200 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
201 if (endpoints_match(ep->ep_description, binding)) {
202 struct dcesrv_if_list *ifl;
203 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
204 if (interface_match(&(ifl->iface), iface)) {
205 return &(ifl->iface);
210 return NULL;
214 see if a uuid and if_version match to an interface
216 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
217 const struct GUID *uuid, uint32_t if_version)
219 return (iface->syntax_id.if_version == if_version &&
220 GUID_equal(&iface->syntax_id.uuid, uuid));
224 find the interface operations on an endpoint by uuid
226 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
227 const struct GUID *uuid, uint32_t if_version)
229 struct dcesrv_if_list *ifl;
230 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
231 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
232 return &(ifl->iface);
235 return NULL;
239 find the earlier parts of a fragmented call awaiting reassembily
241 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
243 struct dcesrv_call_state *c;
244 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
245 if (c->pkt.call_id == call_id) {
246 return c;
249 return NULL;
253 register an interface on an endpoint
255 An endpoint is one unix domain socket (for ncalrpc), one TCP port
256 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
258 Each endpoint can have many interfaces such as netlogon, lsa or
259 samr. Some have essentially the full set.
261 This is driven from the set of interfaces listed in each IDL file
262 via the PIDL generated *__op_init_server() functions.
264 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
265 const char *ep_name,
266 const struct dcesrv_interface *iface,
267 const struct security_descriptor *sd)
269 struct dcesrv_endpoint *ep;
270 struct dcesrv_if_list *ifl;
271 struct dcerpc_binding *binding;
272 bool add_ep = false;
273 NTSTATUS status;
274 enum dcerpc_transport_t transport;
275 char *ep_string = NULL;
276 bool use_single_process = true;
279 * If we are not using handles, there is no need for force
280 * this service into using a single process.
282 * However, due to the way we listen for RPC packets, we can
283 * only do this if we have a single service per pipe or TCP
284 * port, so we still force a single combined process for
285 * ncalrpc.
287 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
288 use_single_process = false;
291 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
293 if (NT_STATUS_IS_ERR(status)) {
294 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
295 return status;
298 transport = dcerpc_binding_get_transport(binding);
299 if (transport == NCACN_IP_TCP) {
300 int port;
301 char port_str[6];
304 * First check if there is already a port specified, eg
305 * for epmapper on ncacn_ip_tcp:[135]
307 const char *endpoint
308 = dcerpc_binding_get_string_option(binding,
309 "endpoint");
310 if (endpoint == NULL) {
311 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
312 "rpc server port", iface->name, 0);
315 * For RPC services that are not set to use a single
316 * process, we do not default to using the 'rpc server
317 * port' because that would cause a double-bind on
318 * that port.
320 if (port == 0 && !use_single_process) {
321 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
323 if (port != 0) {
324 snprintf(port_str, sizeof(port_str), "%u", port);
325 status = dcerpc_binding_set_string_option(binding,
326 "endpoint",
327 port_str);
328 if (!NT_STATUS_IS_OK(status)) {
329 return status;
335 /* see if the interface is already registered on the endpoint */
336 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
337 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
338 iface->name, ep_name));
339 return NT_STATUS_OBJECT_NAME_COLLISION;
342 /* check if this endpoint exists
344 ep = find_endpoint(dce_ctx, binding);
346 if (ep != NULL) {
348 * We want a new port on ncacn_ip_tcp for NETLOGON, so
349 * it can be multi-process. Other processes can also
350 * listen on distinct ports, if they have one forced
351 * in the code above with eg 'rpc server port:drsuapi = 1027'
353 * If we have mulitiple endpoints on port 0, they each
354 * get an epemeral port (currently by walking up from
355 * 1024).
357 if (!use_single_process && transport == NCACN_IP_TCP) {
358 add_ep = true;
362 if (ep == NULL || add_ep) {
363 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
364 if (!ep) {
365 return NT_STATUS_NO_MEMORY;
367 ZERO_STRUCTP(ep);
368 ep->ep_description = talloc_move(ep, &binding);
369 add_ep = true;
371 /* add mgmt interface */
372 ifl = talloc_zero(ep, struct dcesrv_if_list);
373 if (!ifl) {
374 return NT_STATUS_NO_MEMORY;
377 ifl->iface = dcesrv_get_mgmt_interface();
379 DLIST_ADD(ep->interface_list, ifl);
383 * By default don't force into a single process, but if any
384 * interface on this endpoint on this service uses handles
385 * (most do), then we must force into single process mode
387 * By overwriting this each time a new interface is added to
388 * this endpoint, we end up with the most restrictive setting.
390 if (use_single_process) {
391 ep->use_single_process = true;
394 /* talloc a new interface list element */
395 ifl = talloc_zero(ep, struct dcesrv_if_list);
396 if (!ifl) {
397 return NT_STATUS_NO_MEMORY;
400 /* copy the given interface struct to the one on the endpoints interface list */
401 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
403 /* if we have a security descriptor given,
404 * we should see if we can set it up on the endpoint
406 if (sd != NULL) {
407 /* if there's currently no security descriptor given on the endpoint
408 * we try to set it
410 if (ep->sd == NULL) {
411 ep->sd = security_descriptor_copy(ep, sd);
414 /* if now there's no security descriptor given on the endpoint
415 * something goes wrong, either we failed to copy the security descriptor
416 * or there was already one on the endpoint
418 if (ep->sd != NULL) {
419 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
420 " on endpoint '%s'\n",
421 iface->name, ep_name));
422 if (add_ep) free(ep);
423 free(ifl);
424 return NT_STATUS_OBJECT_NAME_COLLISION;
428 /* finally add the interface on the endpoint */
429 DLIST_ADD(ep->interface_list, ifl);
431 /* if it's a new endpoint add it to the dcesrv_context */
432 if (add_ep) {
433 DLIST_ADD(dce_ctx->endpoint_list, ep);
436 /* Re-get the string as we may have set a port */
437 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
439 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
440 iface->name, ep_string));
441 TALLOC_FREE(ep_string);
443 return NT_STATUS_OK;
446 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
447 DATA_BLOB *session_key)
449 if (p->auth_state.session_info->session_key.length) {
450 *session_key = p->auth_state.session_info->session_key;
451 return NT_STATUS_OK;
453 return NT_STATUS_NO_USER_SESSION_KEY;
457 fetch the user session key - may be default (above) or the SMB session key
459 The key is always truncated to 16 bytes
461 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
462 DATA_BLOB *session_key)
464 NTSTATUS status = p->auth_state.session_key(p, session_key);
465 if (!NT_STATUS_IS_OK(status)) {
466 return status;
469 session_key->length = MIN(session_key->length, 16);
471 return NT_STATUS_OK;
475 connect to a dcerpc endpoint
477 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
478 TALLOC_CTX *mem_ctx,
479 const struct dcesrv_endpoint *ep,
480 struct auth_session_info *session_info,
481 struct tevent_context *event_ctx,
482 struct imessaging_context *msg_ctx,
483 struct server_id server_id,
484 uint32_t state_flags,
485 struct dcesrv_connection **_p)
487 struct dcesrv_connection *p;
489 if (!session_info) {
490 return NT_STATUS_ACCESS_DENIED;
493 p = talloc_zero(mem_ctx, struct dcesrv_connection);
494 NT_STATUS_HAVE_NO_MEMORY(p);
496 if (!talloc_reference(p, session_info)) {
497 talloc_free(p);
498 return NT_STATUS_NO_MEMORY;
501 p->dce_ctx = dce_ctx;
502 p->endpoint = ep;
503 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
504 p->auth_state.session_info = session_info;
505 p->auth_state.session_key = dcesrv_generic_session_key;
506 p->event_ctx = event_ctx;
507 p->msg_ctx = msg_ctx;
508 p->server_id = server_id;
509 p->state_flags = state_flags;
510 p->allow_bind = true;
511 p->max_recv_frag = 5840;
512 p->max_xmit_frag = 5840;
513 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
516 * For now we only support NDR32.
518 p->preferred_transfer = &ndr_transfer_syntax_ndr;
520 *_p = p;
521 return NT_STATUS_OK;
525 move a call from an existing linked list to the specified list. This
526 prevents bugs where we forget to remove the call from a previous
527 list when moving it.
529 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
530 enum dcesrv_call_list list)
532 switch (call->list) {
533 case DCESRV_LIST_NONE:
534 break;
535 case DCESRV_LIST_CALL_LIST:
536 DLIST_REMOVE(call->conn->call_list, call);
537 break;
538 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
539 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
540 break;
541 case DCESRV_LIST_PENDING_CALL_LIST:
542 DLIST_REMOVE(call->conn->pending_call_list, call);
543 break;
545 call->list = list;
546 switch (list) {
547 case DCESRV_LIST_NONE:
548 break;
549 case DCESRV_LIST_CALL_LIST:
550 DLIST_ADD_END(call->conn->call_list, call);
551 break;
552 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
553 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
554 break;
555 case DCESRV_LIST_PENDING_CALL_LIST:
556 DLIST_ADD_END(call->conn->pending_call_list, call);
557 break;
561 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
562 const char *reason)
564 if (call->conn->terminate != NULL) {
565 return;
568 call->conn->allow_bind = false;
569 call->conn->allow_alter = false;
570 call->conn->allow_auth3 = false;
571 call->conn->allow_request = false;
573 call->terminate_reason = talloc_strdup(call, reason);
574 if (call->terminate_reason == NULL) {
575 call->terminate_reason = __location__;
580 return a dcerpc bind_nak
582 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
584 struct ncacn_packet pkt;
585 struct dcerpc_bind_nak_version version;
586 struct data_blob_list_item *rep;
587 NTSTATUS status;
588 static const uint8_t _pad[3] = { 0, };
591 * We add the call to the pending_call_list
592 * in order to defer the termination.
594 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
596 /* setup a bind_nak */
597 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
598 pkt.auth_length = 0;
599 pkt.call_id = call->pkt.call_id;
600 pkt.ptype = DCERPC_PKT_BIND_NAK;
601 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
602 pkt.u.bind_nak.reject_reason = reason;
603 version.rpc_vers = 5;
604 version.rpc_vers_minor = 0;
605 pkt.u.bind_nak.num_versions = 1;
606 pkt.u.bind_nak.versions = &version;
607 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
609 rep = talloc_zero(call, struct data_blob_list_item);
610 if (!rep) {
611 return NT_STATUS_NO_MEMORY;
614 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
615 if (!NT_STATUS_IS_OK(status)) {
616 return status;
619 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
621 DLIST_ADD_END(call->replies, rep);
622 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
624 if (call->conn->call_list && call->conn->call_list->replies) {
625 if (call->conn->transport.report_output_data) {
626 call->conn->transport.report_output_data(call->conn);
630 return NT_STATUS_OK;
633 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
634 uint32_t fault_code)
637 * We add the call to the pending_call_list
638 * in order to defer the termination.
640 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
642 return dcesrv_fault_with_flags(call, fault_code,
643 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
646 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
648 DLIST_REMOVE(c->conn->contexts, c);
650 if (c->iface && c->iface->unbind) {
651 c->iface->unbind(c, c->iface);
652 c->iface = NULL;
655 return 0;
658 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
660 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
661 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
662 enum dcerpc_transport_t transport =
663 dcerpc_binding_get_transport(endpoint->ep_description);
664 struct dcesrv_connection_context *context = dce_call->context;
665 const struct dcesrv_interface *iface = context->iface;
667 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
669 if (transport == NCALRPC) {
670 context->allow_connect = true;
671 return;
675 * allow overwrite per interface
676 * allow dcerpc auth level connect:<interface>
678 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
679 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
680 "allow dcerpc auth level connect",
681 iface->name,
682 context->allow_connect);
685 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
686 const struct dcesrv_interface *iface)
688 if (dce_call->context == NULL) {
689 return NT_STATUS_INTERNAL_ERROR;
693 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
694 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
696 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
697 return NT_STATUS_OK;
700 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
701 const struct dcesrv_interface *iface)
703 if (dce_call->context == NULL) {
704 return NT_STATUS_INTERNAL_ERROR;
707 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
708 return NT_STATUS_OK;
711 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
712 const struct dcesrv_interface *iface)
714 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
715 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
716 enum dcerpc_transport_t transport =
717 dcerpc_binding_get_transport(endpoint->ep_description);
718 struct dcesrv_connection_context *context = dce_call->context;
720 if (context == NULL) {
721 return NT_STATUS_INTERNAL_ERROR;
724 if (transport == NCALRPC) {
725 context->allow_connect = true;
726 return NT_STATUS_OK;
730 * allow overwrite per interface
731 * allow dcerpc auth level connect:<interface>
733 context->allow_connect = false;
734 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
735 "allow dcerpc auth level connect",
736 iface->name,
737 context->allow_connect);
738 return NT_STATUS_OK;
741 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
742 const struct dcesrv_interface *iface)
744 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
745 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
746 enum dcerpc_transport_t transport =
747 dcerpc_binding_get_transport(endpoint->ep_description);
748 struct dcesrv_connection_context *context = dce_call->context;
750 if (context == NULL) {
751 return NT_STATUS_INTERNAL_ERROR;
754 if (transport == NCALRPC) {
755 context->allow_connect = true;
756 return NT_STATUS_OK;
760 * allow overwrite per interface
761 * allow dcerpc auth level connect:<interface>
763 context->allow_connect = true;
764 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
765 "allow dcerpc auth level connect",
766 iface->name,
767 context->allow_connect);
768 return NT_STATUS_OK;
772 handle a bind request
774 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
776 struct ncacn_packet *pkt = &call->ack_pkt;
777 struct data_blob_list_item *rep;
778 NTSTATUS status;
779 uint32_t extra_flags = 0;
780 uint16_t max_req = 0;
781 uint16_t max_rep = 0;
782 const char *ep_prefix = "";
783 const char *endpoint = NULL;
784 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
785 struct dcerpc_ack_ctx *ack_features = NULL;
786 size_t i;
788 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
789 DCERPC_PKT_BIND,
790 call->pkt.u.bind.auth_info.length,
791 0, /* required flags */
792 DCERPC_PFC_FLAG_FIRST |
793 DCERPC_PFC_FLAG_LAST |
794 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
795 0x08 | /* this is not defined, but should be ignored */
796 DCERPC_PFC_FLAG_CONC_MPX |
797 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
798 DCERPC_PFC_FLAG_MAYBE |
799 DCERPC_PFC_FLAG_OBJECT_UUID);
800 if (!NT_STATUS_IS_OK(status)) {
801 return dcesrv_bind_nak(call,
802 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
805 /* max_recv_frag and max_xmit_frag result always in the same value! */
806 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
807 call->pkt.u.bind.max_recv_frag);
809 * The values are between 2048 and 5840 tested against Windows 2012R2
810 * via ncacn_ip_tcp on port 135.
812 max_req = MAX(2048, max_req);
813 max_rep = MIN(max_req, call->conn->max_recv_frag);
814 /* They are truncated to an 8 byte boundary. */
815 max_rep &= 0xFFF8;
817 /* max_recv_frag and max_xmit_frag result always in the same value! */
818 call->conn->max_recv_frag = max_rep;
819 call->conn->max_xmit_frag = max_rep;
822 if provided, check the assoc_group is valid
824 if (call->pkt.u.bind.assoc_group_id != 0) {
825 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
826 call->conn->dce_ctx,
827 call->pkt.u.bind.assoc_group_id);
828 } else {
829 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
830 call->conn->dce_ctx);
834 * The NETLOGON server does not use handles and so
835 * there is no need to support association groups, but
836 * we need to give back a number regardless.
838 * We have to do this when it is not run as a single process,
839 * because then it can't see the other valid association
840 * groups. We handle this genericly for all endpoints not
841 * running in single process mode.
843 * We know which endpoint we are on even before checking the
844 * iface UUID, so for simplicity we enforce the same policy
845 * for all interfaces on the endpoint.
847 * This means that where NETLOGON
848 * shares an endpoint (such as ncalrpc or of 'lsa over
849 * netlogon' is set) we will still check association groups.
853 if (call->conn->assoc_group == NULL &&
854 !call->conn->endpoint->use_single_process) {
855 call->conn->assoc_group
856 = dcesrv_assoc_group_new(call->conn,
857 call->conn->dce_ctx);
859 if (call->conn->assoc_group == NULL) {
860 return dcesrv_bind_nak(call, 0);
863 if (call->pkt.u.bind.num_contexts < 1) {
864 return dcesrv_bind_nak(call, 0);
867 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
868 call->pkt.u.bind.num_contexts);
869 if (ack_ctx_list == NULL) {
870 return dcesrv_bind_nak(call, 0);
874 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
875 * dcesrv_check_or_create_context()) and do some protocol validation
876 * and set sane defaults.
878 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
879 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
880 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
881 bool is_feature = false;
882 uint64_t features = 0;
884 if (c->num_transfer_syntaxes == 0) {
885 return dcesrv_bind_nak(call, 0);
888 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
889 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
892 * It's only treated as bind time feature request, if the first
893 * transfer_syntax matches, all others are ignored.
895 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
896 &features);
897 if (!is_feature) {
898 continue;
901 if (ack_features != NULL) {
903 * Only one bind time feature context is allowed.
905 return dcesrv_bind_nak(call, 0);
907 ack_features = a;
909 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
910 a->reason.negotiate = 0;
911 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
912 /* not supported yet */
914 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
915 a->reason.negotiate |=
916 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
919 call->conn->bind_time_features = a->reason.negotiate;
923 * Try to negotiate one new presentation context.
925 * Deep in here we locate the iface (by uuid) that the client
926 * requested, from the list of interfaces on the
927 * call->conn->endpoint, and call iface->bind() on that iface.
929 * call->conn was set up at the accept() of the socket, and
930 * call->conn->endpoint has a list of interfaces restricted to
931 * this port or pipe.
933 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
934 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
935 return dcesrv_bind_nak(call, 0);
937 if (!NT_STATUS_IS_OK(status)) {
938 return status;
942 * At this point we still don't know which interface (eg
943 * netlogon, lsa, drsuapi) the caller requested in this bind!
944 * The most recently added context is available as the first
945 * element in the linked list at call->conn->contexts, that is
946 * call->conn->contexts->iface, but they may not have
947 * requested one at all!
950 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
951 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
952 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
953 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
956 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
957 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
961 * After finding the interface and setting up the NDR
962 * transport negotiation etc, handle any authentication that
963 * is being requested.
965 if (!dcesrv_auth_bind(call)) {
966 struct dcesrv_auth *auth = &call->conn->auth_state;
968 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
970 * With DCERPC_AUTH_LEVEL_NONE, we get the
971 * reject_reason in auth->auth_context_id.
973 return dcesrv_bind_nak(call, auth->auth_context_id);
977 * This must a be a temporary failure e.g. talloc or invalid
978 * configuration, e.g. no machine account.
980 return dcesrv_bind_nak(call,
981 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
984 /* setup a bind_ack */
985 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
986 pkt->auth_length = 0;
987 pkt->call_id = call->pkt.call_id;
988 pkt->ptype = DCERPC_PKT_BIND_ACK;
989 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
990 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
991 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
992 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
994 endpoint = dcerpc_binding_get_string_option(
995 call->conn->endpoint->ep_description,
996 "endpoint");
997 if (endpoint == NULL) {
998 endpoint = "";
1001 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1003 * TODO: check if this is really needed
1005 * Or if we should fix this in our idl files.
1007 ep_prefix = "\\PIPE\\";
1008 endpoint += 6;
1011 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1012 ep_prefix,
1013 endpoint);
1014 if (pkt->u.bind_ack.secondary_address == NULL) {
1015 return NT_STATUS_NO_MEMORY;
1017 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1018 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1019 pkt->u.bind_ack.auth_info = data_blob_null;
1021 status = dcesrv_auth_bind_ack(call, pkt);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 return dcesrv_bind_nak(call, 0);
1026 rep = talloc_zero(call, struct data_blob_list_item);
1027 if (!rep) {
1028 return NT_STATUS_NO_MEMORY;
1031 status = ncacn_push_auth(&rep->blob, call, pkt,
1032 call->out_auth_info);
1033 if (!NT_STATUS_IS_OK(status)) {
1034 return status;
1037 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1039 DLIST_ADD_END(call->replies, rep);
1040 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1042 if (call->conn->call_list && call->conn->call_list->replies) {
1043 if (call->conn->transport.report_output_data) {
1044 call->conn->transport.report_output_data(call->conn);
1048 return NT_STATUS_OK;
1053 handle a auth3 request
1055 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1057 NTSTATUS status;
1059 if (!call->conn->allow_auth3) {
1060 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1063 if (call->conn->auth_state.auth_finished) {
1064 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1067 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1068 DCERPC_PKT_AUTH3,
1069 call->pkt.u.auth3.auth_info.length,
1070 0, /* required flags */
1071 DCERPC_PFC_FLAG_FIRST |
1072 DCERPC_PFC_FLAG_LAST |
1073 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1074 0x08 | /* this is not defined, but should be ignored */
1075 DCERPC_PFC_FLAG_CONC_MPX |
1076 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1077 DCERPC_PFC_FLAG_MAYBE |
1078 DCERPC_PFC_FLAG_OBJECT_UUID);
1079 if (!NT_STATUS_IS_OK(status)) {
1080 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1083 /* handle the auth3 in the auth code */
1084 if (!dcesrv_auth_auth3(call)) {
1085 call->conn->auth_state.auth_invalid = true;
1086 if (call->fault_code != 0) {
1087 return dcesrv_fault_disconnect(call, call->fault_code);
1091 talloc_free(call);
1093 /* we don't send a reply to a auth3 request, except by a
1094 fault */
1095 return NT_STATUS_OK;
1099 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1100 const struct dcerpc_bind *b,
1101 const struct dcerpc_ctx_list *ctx,
1102 struct dcerpc_ack_ctx *ack,
1103 bool validate_only,
1104 const struct ndr_syntax_id *supported_transfer)
1106 uint32_t if_version;
1107 struct dcesrv_connection_context *context;
1108 const struct dcesrv_interface *iface;
1109 struct GUID uuid;
1110 NTSTATUS status;
1111 const struct ndr_syntax_id *selected_transfer = NULL;
1112 size_t i;
1113 bool ok;
1115 if (b == NULL) {
1116 return NT_STATUS_INTERNAL_ERROR;
1118 if (ctx == NULL) {
1119 return NT_STATUS_INTERNAL_ERROR;
1121 if (ctx->num_transfer_syntaxes < 1) {
1122 return NT_STATUS_INTERNAL_ERROR;
1124 if (ack == NULL) {
1125 return NT_STATUS_INTERNAL_ERROR;
1127 if (supported_transfer == NULL) {
1128 return NT_STATUS_INTERNAL_ERROR;
1131 switch (ack->result) {
1132 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1133 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1135 * We is already completed.
1137 return NT_STATUS_OK;
1138 default:
1139 break;
1142 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1143 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1145 if_version = ctx->abstract_syntax.if_version;
1146 uuid = ctx->abstract_syntax.uuid;
1148 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1149 if (iface == NULL) {
1150 char *uuid_str = GUID_string(call, &uuid);
1151 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1152 talloc_free(uuid_str);
1154 * We report this only via ack->result
1156 return NT_STATUS_OK;
1159 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1160 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1162 if (validate_only) {
1164 * We report this only via ack->result
1166 return NT_STATUS_OK;
1169 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1171 * we only do NDR encoded dcerpc for now.
1173 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1174 supported_transfer);
1175 if (ok) {
1176 selected_transfer = supported_transfer;
1177 break;
1181 context = dcesrv_find_context(call->conn, ctx->context_id);
1182 if (context != NULL) {
1183 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1184 &ctx->abstract_syntax);
1185 if (!ok) {
1186 return NT_STATUS_RPC_PROTOCOL_ERROR;
1189 if (selected_transfer != NULL) {
1190 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1191 selected_transfer);
1192 if (!ok) {
1193 return NT_STATUS_RPC_PROTOCOL_ERROR;
1196 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1197 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1198 ack->syntax = context->transfer_syntax;
1202 * We report this only via ack->result
1204 return NT_STATUS_OK;
1207 if (selected_transfer == NULL) {
1209 * We report this only via ack->result
1211 return NT_STATUS_OK;
1214 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1215 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1217 /* add this context to the list of available context_ids */
1218 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1219 if (context == NULL) {
1220 return NT_STATUS_NO_MEMORY;
1222 context->conn = call->conn;
1223 context->context_id = ctx->context_id;
1224 context->iface = iface;
1225 context->transfer_syntax = *selected_transfer;
1226 context->private_data = NULL;
1227 DLIST_ADD(call->conn->contexts, context);
1228 call->context = context;
1229 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1231 dcesrv_prepare_context_auth(call);
1234 * Multiplex is supported by default
1236 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1238 status = iface->bind(call, iface, if_version);
1239 call->context = NULL;
1240 if (!NT_STATUS_IS_OK(status)) {
1241 /* we don't want to trigger the iface->unbind() hook */
1242 context->iface = NULL;
1243 talloc_free(context);
1245 * We report this only via ack->result
1247 return NT_STATUS_OK;
1250 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1251 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1252 ack->syntax = context->transfer_syntax;
1253 return NT_STATUS_OK;
1256 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1257 const struct dcerpc_bind *b,
1258 struct dcerpc_ack_ctx *ack_ctx_list)
1260 NTSTATUS status;
1261 size_t i;
1262 bool validate_only = false;
1263 bool preferred_ndr32;
1266 * Try to negotiate one new presentation context,
1267 * using our preferred transfer syntax.
1269 for (i = 0; i < b->num_contexts; i++) {
1270 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1271 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1273 status = dcesrv_check_or_create_context(call, b, c, a,
1274 validate_only,
1275 call->conn->preferred_transfer);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 return status;
1280 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1282 * We managed to negotiate one context.
1284 * => we're done.
1286 validate_only = true;
1290 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1291 call->conn->preferred_transfer);
1292 if (preferred_ndr32) {
1294 * We're done.
1296 return NT_STATUS_OK;
1300 * Try to negotiate one new presentation context,
1301 * using NDR 32 as fallback.
1303 for (i = 0; i < b->num_contexts; i++) {
1304 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1305 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1307 status = dcesrv_check_or_create_context(call, b, c, a,
1308 validate_only,
1309 &ndr_transfer_syntax_ndr);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 return status;
1314 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1316 * We managed to negotiate one context.
1318 * => we're done.
1320 validate_only = true;
1324 return NT_STATUS_OK;
1328 handle a alter context request
1330 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1332 NTSTATUS status;
1333 bool auth_ok = false;
1334 struct ncacn_packet *pkt = &call->ack_pkt;
1335 uint32_t extra_flags = 0;
1336 struct data_blob_list_item *rep = NULL;
1337 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1338 size_t i;
1340 if (!call->conn->allow_alter) {
1341 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1344 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1345 DCERPC_PKT_ALTER,
1346 call->pkt.u.alter.auth_info.length,
1347 0, /* required flags */
1348 DCERPC_PFC_FLAG_FIRST |
1349 DCERPC_PFC_FLAG_LAST |
1350 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1351 0x08 | /* this is not defined, but should be ignored */
1352 DCERPC_PFC_FLAG_CONC_MPX |
1353 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1354 DCERPC_PFC_FLAG_MAYBE |
1355 DCERPC_PFC_FLAG_OBJECT_UUID);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1360 auth_ok = dcesrv_auth_alter(call);
1361 if (!auth_ok) {
1362 if (call->fault_code != 0) {
1363 return dcesrv_fault_disconnect(call, call->fault_code);
1367 if (call->pkt.u.alter.num_contexts < 1) {
1368 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1371 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1372 call->pkt.u.alter.num_contexts);
1373 if (ack_ctx_list == NULL) {
1374 return NT_STATUS_NO_MEMORY;
1378 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1379 * dcesrv_check_or_create_context()) and do some protocol validation
1380 * and set sane defaults.
1382 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1383 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1384 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1386 if (c->num_transfer_syntaxes == 0) {
1387 return dcesrv_fault_disconnect(call,
1388 DCERPC_NCA_S_PROTO_ERROR);
1391 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1392 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1396 * Try to negotiate one new presentation context.
1398 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1399 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1400 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1402 if (!NT_STATUS_IS_OK(status)) {
1403 return status;
1406 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1407 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1408 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1409 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1412 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1413 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1416 /* handle any authentication that is being requested */
1417 if (!auth_ok) {
1418 if (call->in_auth_info.auth_type !=
1419 call->conn->auth_state.auth_type)
1421 return dcesrv_fault_disconnect(call,
1422 DCERPC_FAULT_SEC_PKG_ERROR);
1424 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1427 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1428 pkt->auth_length = 0;
1429 pkt->call_id = call->pkt.call_id;
1430 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1431 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1432 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1433 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1434 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1435 pkt->u.alter_resp.secondary_address = "";
1436 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1437 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1438 pkt->u.alter_resp.auth_info = data_blob_null;
1440 status = dcesrv_auth_alter_ack(call, pkt);
1441 if (!NT_STATUS_IS_OK(status)) {
1442 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1445 rep = talloc_zero(call, struct data_blob_list_item);
1446 if (!rep) {
1447 return NT_STATUS_NO_MEMORY;
1450 status = ncacn_push_auth(&rep->blob, call, pkt, call->out_auth_info);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 return status;
1455 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1457 DLIST_ADD_END(call->replies, rep);
1458 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1460 if (call->conn->call_list && call->conn->call_list->replies) {
1461 if (call->conn->transport.report_output_data) {
1462 call->conn->transport.report_output_data(call->conn);
1466 return NT_STATUS_OK;
1470 possibly save the call for inspection with ndrdump
1472 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1474 #ifdef DEVELOPER
1475 char *fname;
1476 const char *dump_dir;
1477 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1478 if (!dump_dir) {
1479 return;
1481 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1482 dump_dir,
1483 call->context->iface->name,
1484 call->pkt.u.request.opnum,
1485 why);
1486 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1487 DEBUG(0,("RPC SAVED %s\n", fname));
1489 talloc_free(fname);
1490 #endif
1493 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1495 TALLOC_CTX *frame = talloc_stackframe();
1496 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1497 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1498 const struct dcerpc_sec_vt_pcontext pcontext = {
1499 .abstract_syntax = call->context->iface->syntax_id,
1500 .transfer_syntax = call->context->transfer_syntax,
1502 const struct dcerpc_sec_vt_header2 header2 =
1503 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1504 enum ndr_err_code ndr_err;
1505 struct dcerpc_sec_verification_trailer *vt = NULL;
1506 NTSTATUS status = NT_STATUS_OK;
1507 bool ok;
1509 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1511 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1512 frame, &vt);
1513 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1514 status = ndr_map_error2ntstatus(ndr_err);
1515 goto done;
1518 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1519 &pcontext, &header2);
1520 if (!ok) {
1521 status = NT_STATUS_ACCESS_DENIED;
1522 goto done;
1524 done:
1525 TALLOC_FREE(frame);
1526 return status;
1530 handle a dcerpc request packet
1532 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1534 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1535 enum dcerpc_transport_t transport =
1536 dcerpc_binding_get_transport(endpoint->ep_description);
1537 struct ndr_pull *pull;
1538 NTSTATUS status;
1540 if (!call->conn->allow_request) {
1541 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1544 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1545 if (call->conn->auth_state.gensec_security &&
1546 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1547 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1550 if (call->context == NULL) {
1551 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1552 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1555 switch (call->conn->auth_state.auth_level) {
1556 case DCERPC_AUTH_LEVEL_NONE:
1557 case DCERPC_AUTH_LEVEL_PACKET:
1558 case DCERPC_AUTH_LEVEL_INTEGRITY:
1559 case DCERPC_AUTH_LEVEL_PRIVACY:
1560 break;
1561 default:
1562 if (!call->context->allow_connect) {
1563 char *addr;
1565 addr = tsocket_address_string(call->conn->remote_address,
1566 call);
1568 DEBUG(2, ("%s: restrict auth_level_connect access "
1569 "to [%s] with auth[type=0x%x,level=0x%x] "
1570 "on [%s] from [%s]\n",
1571 __func__, call->context->iface->name,
1572 call->conn->auth_state.auth_type,
1573 call->conn->auth_state.auth_level,
1574 derpc_transport_string_by_transport(transport),
1575 addr));
1576 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1578 break;
1581 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1582 char *addr;
1584 addr = tsocket_address_string(call->conn->remote_address, call);
1586 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1587 "to [%s] with auth[type=0x%x,level=0x%x] "
1588 "on [%s] from [%s]\n",
1589 __func__,
1590 call->context->min_auth_level,
1591 call->context->iface->name,
1592 call->conn->auth_state.auth_type,
1593 call->conn->auth_state.auth_level,
1594 derpc_transport_string_by_transport(transport),
1595 addr));
1596 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1599 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1600 NT_STATUS_HAVE_NO_MEMORY(pull);
1602 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1604 call->ndr_pull = pull;
1606 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1607 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1610 status = dcesrv_check_verification_trailer(call);
1611 if (!NT_STATUS_IS_OK(status)) {
1612 uint32_t faultcode = DCERPC_FAULT_OTHER;
1613 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1614 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1616 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1617 nt_errstr(status)));
1618 return dcesrv_fault(call, faultcode);
1621 /* unravel the NDR for the packet */
1622 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1623 if (!NT_STATUS_IS_OK(status)) {
1624 uint8_t extra_flags = 0;
1625 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1626 /* we got an unknown call */
1627 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1628 call->pkt.u.request.opnum,
1629 call->context->iface->name));
1630 dcesrv_save_call(call, "unknown");
1631 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1632 } else {
1633 dcesrv_save_call(call, "pullfail");
1635 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1638 if (pull->offset != pull->data_size) {
1639 dcesrv_save_call(call, "extrabytes");
1640 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1641 pull->data_size - pull->offset));
1644 /* call the dispatch function */
1645 status = call->context->iface->dispatch(call, call, call->r);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1648 call->context->iface->name,
1649 call->pkt.u.request.opnum,
1650 dcerpc_errstr(pull, call->fault_code)));
1651 return dcesrv_fault(call, call->fault_code);
1654 /* add the call to the pending list */
1655 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1657 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1658 return NT_STATUS_OK;
1661 return dcesrv_reply(call);
1666 remove the call from the right list when freed
1668 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1670 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1671 return 0;
1674 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1676 return conn->local_address;
1679 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1681 return conn->remote_address;
1685 process some input to a dcerpc endpoint server.
1687 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1688 struct ncacn_packet *pkt,
1689 DATA_BLOB blob)
1691 NTSTATUS status;
1692 struct dcesrv_call_state *call;
1693 struct dcesrv_call_state *existing = NULL;
1695 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1696 if (!call) {
1697 data_blob_free(&blob);
1698 talloc_free(pkt);
1699 return NT_STATUS_NO_MEMORY;
1701 call->conn = dce_conn;
1702 call->event_ctx = dce_conn->event_ctx;
1703 call->msg_ctx = dce_conn->msg_ctx;
1704 call->state_flags = call->conn->state_flags;
1705 call->time = timeval_current();
1706 call->list = DCESRV_LIST_NONE;
1708 talloc_steal(call, pkt);
1709 talloc_steal(call, blob.data);
1710 call->pkt = *pkt;
1712 talloc_set_destructor(call, dcesrv_call_dequeue);
1714 if (call->conn->allow_bind) {
1716 * Only one bind is possible per connection
1718 call->conn->allow_bind = false;
1719 return dcesrv_bind(call);
1722 /* we have to check the signing here, before combining the
1723 pdus */
1724 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1725 if (!call->conn->allow_request) {
1726 return dcesrv_fault_disconnect(call,
1727 DCERPC_NCA_S_PROTO_ERROR);
1730 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1731 DCERPC_PKT_REQUEST,
1732 call->pkt.u.request.stub_and_verifier.length,
1733 0, /* required_flags */
1734 DCERPC_PFC_FLAG_FIRST |
1735 DCERPC_PFC_FLAG_LAST |
1736 DCERPC_PFC_FLAG_PENDING_CANCEL |
1737 0x08 | /* this is not defined, but should be ignored */
1738 DCERPC_PFC_FLAG_CONC_MPX |
1739 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1740 DCERPC_PFC_FLAG_MAYBE |
1741 DCERPC_PFC_FLAG_OBJECT_UUID);
1742 if (!NT_STATUS_IS_OK(status)) {
1743 return dcesrv_fault_disconnect(call,
1744 DCERPC_NCA_S_PROTO_ERROR);
1747 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1749 * We don't use dcesrv_fault_disconnect()
1750 * here, because we don't want to set
1751 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1753 * Note that we don't check against the negotiated
1754 * max_recv_frag, but a hard coded value.
1756 dcesrv_call_disconnect_after(call,
1757 "dcesrv_auth_request - frag_length too large");
1758 return dcesrv_fault(call,
1759 DCERPC_NCA_S_PROTO_ERROR);
1762 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1763 if (dce_conn->pending_call_list != NULL) {
1765 * concurrent requests are only allowed
1766 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1768 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1769 dcesrv_call_disconnect_after(call,
1770 "dcesrv_auth_request - "
1771 "existing pending call without CONN_MPX");
1772 return dcesrv_fault(call,
1773 DCERPC_NCA_S_PROTO_ERROR);
1776 /* only one request is possible in the fragmented list */
1777 if (dce_conn->incoming_fragmented_call_list != NULL) {
1778 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1780 * Without DCERPC_PFC_FLAG_CONC_MPX
1781 * we need to return the FAULT on the
1782 * already existing call.
1784 * This is important to get the
1785 * call_id and context_id right.
1787 TALLOC_FREE(call);
1788 call = dce_conn->incoming_fragmented_call_list;
1790 dcesrv_call_disconnect_after(call,
1791 "dcesrv_auth_request - "
1792 "existing fragmented call");
1793 return dcesrv_fault(call,
1794 DCERPC_NCA_S_PROTO_ERROR);
1796 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1797 return dcesrv_fault_disconnect(call,
1798 DCERPC_FAULT_NO_CALL_ACTIVE);
1800 call->context = dcesrv_find_context(call->conn,
1801 call->pkt.u.request.context_id);
1802 if (call->context == NULL) {
1803 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1804 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1806 } else {
1807 const struct dcerpc_request *nr = &call->pkt.u.request;
1808 const struct dcerpc_request *er = NULL;
1809 int cmp;
1811 existing = dcesrv_find_fragmented_call(dce_conn,
1812 call->pkt.call_id);
1813 if (existing == NULL) {
1814 dcesrv_call_disconnect_after(call,
1815 "dcesrv_auth_request - "
1816 "no existing fragmented call");
1817 return dcesrv_fault(call,
1818 DCERPC_NCA_S_PROTO_ERROR);
1820 er = &existing->pkt.u.request;
1822 if (call->pkt.ptype != existing->pkt.ptype) {
1823 /* trying to play silly buggers are we? */
1824 return dcesrv_fault_disconnect(existing,
1825 DCERPC_NCA_S_PROTO_ERROR);
1827 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1828 sizeof(pkt->drep));
1829 if (cmp != 0) {
1830 return dcesrv_fault_disconnect(existing,
1831 DCERPC_NCA_S_PROTO_ERROR);
1833 if (nr->context_id != er->context_id) {
1834 return dcesrv_fault_disconnect(existing,
1835 DCERPC_NCA_S_PROTO_ERROR);
1837 if (nr->opnum != er->opnum) {
1838 return dcesrv_fault_disconnect(existing,
1839 DCERPC_NCA_S_PROTO_ERROR);
1844 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1845 bool ok;
1846 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1848 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1849 payload_offset += 16;
1852 ok = dcesrv_auth_pkt_pull(call, &blob,
1853 0, /* required_flags */
1854 DCERPC_PFC_FLAG_FIRST |
1855 DCERPC_PFC_FLAG_LAST |
1856 DCERPC_PFC_FLAG_PENDING_CANCEL |
1857 0x08 | /* this is not defined, but should be ignored */
1858 DCERPC_PFC_FLAG_CONC_MPX |
1859 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1860 DCERPC_PFC_FLAG_MAYBE |
1861 DCERPC_PFC_FLAG_OBJECT_UUID,
1862 payload_offset,
1863 &call->pkt.u.request.stub_and_verifier);
1864 if (!ok) {
1866 * We don't use dcesrv_fault_disconnect()
1867 * here, because we don't want to set
1868 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1870 dcesrv_call_disconnect_after(call,
1871 "dcesrv_auth_request - failed");
1872 if (call->fault_code == 0) {
1873 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1875 return dcesrv_fault(call, call->fault_code);
1879 /* see if this is a continued packet */
1880 if (existing != NULL) {
1881 struct dcerpc_request *er = &existing->pkt.u.request;
1882 const struct dcerpc_request *nr = &call->pkt.u.request;
1883 size_t available;
1884 size_t alloc_size;
1885 size_t alloc_hint;
1888 * Up to 4 MByte are allowed by all fragments
1890 available = dce_conn->max_total_request_size;
1891 if (er->stub_and_verifier.length > available) {
1892 dcesrv_call_disconnect_after(existing,
1893 "dcesrv_auth_request - existing payload too large");
1894 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1896 available -= er->stub_and_verifier.length;
1897 if (nr->alloc_hint > available) {
1898 dcesrv_call_disconnect_after(existing,
1899 "dcesrv_auth_request - alloc hint too large");
1900 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1902 if (nr->stub_and_verifier.length > available) {
1903 dcesrv_call_disconnect_after(existing,
1904 "dcesrv_auth_request - new payload too large");
1905 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1907 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1908 /* allocate at least 1 byte */
1909 alloc_hint = MAX(alloc_hint, 1);
1910 alloc_size = er->stub_and_verifier.length +
1911 nr->stub_and_verifier.length;
1912 alloc_size = MAX(alloc_size, alloc_hint);
1914 er->stub_and_verifier.data =
1915 talloc_realloc(existing,
1916 er->stub_and_verifier.data,
1917 uint8_t, alloc_size);
1918 if (er->stub_and_verifier.data == NULL) {
1919 TALLOC_FREE(call);
1920 return dcesrv_fault_with_flags(existing,
1921 DCERPC_FAULT_OUT_OF_RESOURCES,
1922 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1924 memcpy(er->stub_and_verifier.data +
1925 er->stub_and_verifier.length,
1926 nr->stub_and_verifier.data,
1927 nr->stub_and_verifier.length);
1928 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1930 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1932 TALLOC_FREE(call);
1933 call = existing;
1936 /* this may not be the last pdu in the chain - if its isn't then
1937 just put it on the incoming_fragmented_call_list and wait for the rest */
1938 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1939 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1941 * Up to 4 MByte are allowed by all fragments
1943 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1944 dcesrv_call_disconnect_after(call,
1945 "dcesrv_auth_request - initial alloc hint too large");
1946 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1948 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1949 return NT_STATUS_OK;
1952 /* This removes any fragments we may have had stashed away */
1953 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1955 switch (call->pkt.ptype) {
1956 case DCERPC_PKT_BIND:
1957 status = dcesrv_bind_nak(call,
1958 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1959 break;
1960 case DCERPC_PKT_AUTH3:
1961 status = dcesrv_auth3(call);
1962 break;
1963 case DCERPC_PKT_ALTER:
1964 status = dcesrv_alter(call);
1965 break;
1966 case DCERPC_PKT_REQUEST:
1967 status = dcesrv_request(call);
1968 break;
1969 case DCERPC_PKT_CO_CANCEL:
1970 case DCERPC_PKT_ORPHANED:
1972 * Window just ignores CO_CANCEL and ORPHANED,
1973 * so we do...
1975 status = NT_STATUS_OK;
1976 TALLOC_FREE(call);
1977 break;
1978 case DCERPC_PKT_BIND_ACK:
1979 case DCERPC_PKT_BIND_NAK:
1980 case DCERPC_PKT_ALTER_RESP:
1981 case DCERPC_PKT_RESPONSE:
1982 case DCERPC_PKT_FAULT:
1983 case DCERPC_PKT_SHUTDOWN:
1984 default:
1985 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1986 break;
1989 /* if we are going to be sending a reply then add
1990 it to the list of pending calls. We add it to the end to keep the call
1991 list in the order we will answer */
1992 if (!NT_STATUS_IS_OK(status)) {
1993 talloc_free(call);
1996 return status;
1999 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2000 struct loadparm_context *lp_ctx,
2001 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2003 NTSTATUS status;
2004 struct dcesrv_context *dce_ctx;
2005 int i;
2007 if (!endpoint_servers) {
2008 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2009 return NT_STATUS_INTERNAL_ERROR;
2012 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2013 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2015 if (uid_wrapper_enabled()) {
2016 setenv("UID_WRAPPER_MYUID", "1", 1);
2018 dce_ctx->initial_euid = geteuid();
2019 if (uid_wrapper_enabled()) {
2020 unsetenv("UID_WRAPPER_MYUID");
2023 dce_ctx->endpoint_list = NULL;
2024 dce_ctx->lp_ctx = lp_ctx;
2025 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2026 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2027 dce_ctx->broken_connections = NULL;
2029 for (i=0;endpoint_servers[i];i++) {
2030 const struct dcesrv_endpoint_server *ep_server;
2032 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2033 if (!ep_server) {
2034 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2035 return NT_STATUS_INTERNAL_ERROR;
2038 status = ep_server->init_server(dce_ctx, ep_server);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2041 nt_errstr(status)));
2042 return status;
2046 *_dce_ctx = dce_ctx;
2047 return NT_STATUS_OK;
2050 /* the list of currently registered DCERPC endpoint servers.
2052 static struct ep_server {
2053 struct dcesrv_endpoint_server *ep_server;
2054 } *ep_servers = NULL;
2055 static int num_ep_servers;
2058 register a DCERPC endpoint server.
2060 The 'name' can be later used by other backends to find the operations
2061 structure for this backend.
2064 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2067 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2068 /* its already registered! */
2069 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2070 ep_server->name));
2071 return NT_STATUS_OBJECT_NAME_COLLISION;
2074 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2075 if (!ep_servers) {
2076 smb_panic("out of memory in dcerpc_register");
2079 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2080 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2082 num_ep_servers++;
2084 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2085 ep_server->name));
2087 return NT_STATUS_OK;
2091 return the operations structure for a named backend of the specified type
2093 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2095 int i;
2097 for (i=0;i<num_ep_servers;i++) {
2098 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2099 return ep_servers[i].ep_server;
2103 return NULL;
2106 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2108 static bool initialized;
2109 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2110 STATIC_dcerpc_server_MODULES_PROTO;
2111 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2112 init_module_fn *shared_init;
2114 if (initialized) {
2115 return;
2117 initialized = true;
2119 shared_init = load_samba_modules(NULL, "dcerpc_server");
2121 run_init_functions(NULL, static_init);
2122 run_init_functions(NULL, shared_init);
2124 talloc_free(shared_init);
2128 return the DCERPC module version, and the size of some critical types
2129 This can be used by endpoint server modules to either detect compilation errors, or provide
2130 multiple implementations for different smbd compilation options in one module
2132 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2134 static const struct dcesrv_critical_sizes critical_sizes = {
2135 DCERPC_MODULE_VERSION,
2136 sizeof(struct dcesrv_context),
2137 sizeof(struct dcesrv_endpoint),
2138 sizeof(struct dcesrv_endpoint_server),
2139 sizeof(struct dcesrv_interface),
2140 sizeof(struct dcesrv_if_list),
2141 sizeof(struct dcesrv_connection),
2142 sizeof(struct dcesrv_call_state),
2143 sizeof(struct dcesrv_auth),
2144 sizeof(struct dcesrv_handle)
2147 return &critical_sizes;
2150 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2152 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2153 struct stream_connection *srv_conn;
2154 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2155 struct stream_connection);
2157 dce_conn->wait_send = NULL;
2158 dce_conn->wait_recv = NULL;
2159 dce_conn->wait_private = NULL;
2161 dce_conn->allow_bind = false;
2162 dce_conn->allow_auth3 = false;
2163 dce_conn->allow_alter = false;
2164 dce_conn->allow_request = false;
2166 if (dce_conn->pending_call_list == NULL) {
2167 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2169 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2170 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2171 return;
2174 if (dce_conn->terminate != NULL) {
2175 return;
2178 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2179 reason));
2180 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2181 if (dce_conn->terminate == NULL) {
2182 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2184 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2187 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2189 struct dcesrv_connection *cur, *next;
2191 next = dce_ctx->broken_connections;
2192 while (next != NULL) {
2193 cur = next;
2194 next = cur->next;
2196 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2197 struct dcesrv_connection_context *context_cur, *context_next;
2199 context_next = cur->contexts;
2200 while (context_next != NULL) {
2201 context_cur = context_next;
2202 context_next = context_cur->next;
2204 dcesrv_connection_context_destructor(context_cur);
2208 dcesrv_terminate_connection(cur, cur->terminate);
2212 /* We need this include to be able to compile on some plateforms
2213 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2214 * correctly.
2215 * It has to be that deep because otherwise we have a conflict on
2216 * const struct dcesrv_interface declaration.
2217 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2218 * which conflict with the bind used before.
2220 #include "system/network.h"
2222 struct dcesrv_sock_reply_state {
2223 struct dcesrv_connection *dce_conn;
2224 struct dcesrv_call_state *call;
2225 struct iovec iov;
2228 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2229 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2231 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2233 struct dcesrv_call_state *call;
2235 call = dce_conn->call_list;
2236 if (!call || !call->replies) {
2237 return;
2240 while (call->replies) {
2241 struct data_blob_list_item *rep = call->replies;
2242 struct dcesrv_sock_reply_state *substate;
2243 struct tevent_req *subreq;
2245 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2246 if (!substate) {
2247 dcesrv_terminate_connection(dce_conn, "no memory");
2248 return;
2251 substate->dce_conn = dce_conn;
2252 substate->call = NULL;
2254 DLIST_REMOVE(call->replies, rep);
2256 if (call->replies == NULL && call->terminate_reason == NULL) {
2257 substate->call = call;
2260 substate->iov.iov_base = (void *) rep->blob.data;
2261 substate->iov.iov_len = rep->blob.length;
2263 subreq = tstream_writev_queue_send(substate,
2264 dce_conn->event_ctx,
2265 dce_conn->stream,
2266 dce_conn->send_queue,
2267 &substate->iov, 1);
2268 if (!subreq) {
2269 dcesrv_terminate_connection(dce_conn, "no memory");
2270 return;
2272 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2273 substate);
2276 if (call->terminate_reason != NULL) {
2277 struct tevent_req *subreq;
2279 subreq = tevent_queue_wait_send(call,
2280 dce_conn->event_ctx,
2281 dce_conn->send_queue);
2282 if (!subreq) {
2283 dcesrv_terminate_connection(dce_conn, __location__);
2284 return;
2286 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2287 call);
2290 DLIST_REMOVE(call->conn->call_list, call);
2291 call->list = DCESRV_LIST_NONE;
2294 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2296 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2297 struct dcesrv_sock_reply_state);
2298 int ret;
2299 int sys_errno;
2300 NTSTATUS status;
2301 struct dcesrv_call_state *call = substate->call;
2303 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2304 TALLOC_FREE(subreq);
2305 if (ret == -1) {
2306 status = map_nt_error_from_unix_common(sys_errno);
2307 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2308 return;
2311 talloc_free(substate);
2312 if (call) {
2313 talloc_free(call);
2317 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2319 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2321 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2322 struct dcesrv_call_state);
2323 bool ok;
2324 struct timeval tv;
2326 /* make sure we stop send queue before removing subreq */
2327 tevent_queue_stop(call->conn->send_queue);
2329 ok = tevent_queue_wait_recv(subreq);
2330 TALLOC_FREE(subreq);
2331 if (!ok) {
2332 dcesrv_terminate_connection(call->conn, __location__);
2333 return;
2336 /* disconnect after 200 usecs */
2337 tv = timeval_current_ofs_usec(200);
2338 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2339 if (subreq == NULL) {
2340 dcesrv_terminate_connection(call->conn, __location__);
2341 return;
2343 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2344 call);
2347 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2349 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2350 struct dcesrv_call_state);
2351 bool ok;
2353 ok = tevent_wakeup_recv(subreq);
2354 TALLOC_FREE(subreq);
2355 if (!ok) {
2356 dcesrv_terminate_connection(call->conn, __location__);
2357 return;
2360 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2363 struct dcesrv_socket_context {
2364 const struct dcesrv_endpoint *endpoint;
2365 struct dcesrv_context *dcesrv_ctx;
2369 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2371 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2373 NTSTATUS status;
2374 struct dcesrv_socket_context *dcesrv_sock =
2375 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2376 enum dcerpc_transport_t transport =
2377 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2378 struct dcesrv_connection *dcesrv_conn = NULL;
2379 int ret;
2380 struct tevent_req *subreq;
2381 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2383 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2385 if (!srv_conn->session_info) {
2386 status = auth_anonymous_session_info(srv_conn,
2387 lp_ctx,
2388 &srv_conn->session_info);
2389 if (!NT_STATUS_IS_OK(status)) {
2390 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2391 nt_errstr(status)));
2392 stream_terminate_connection(srv_conn, nt_errstr(status));
2393 return;
2398 * This fills in dcesrv_conn->endpoint with the endpoint
2399 * associated with the socket. From this point on we know
2400 * which (group of) services we are handling, but not the
2401 * specific interface.
2404 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2405 srv_conn,
2406 dcesrv_sock->endpoint,
2407 srv_conn->session_info,
2408 srv_conn->event.ctx,
2409 srv_conn->msg_ctx,
2410 srv_conn->server_id,
2411 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2412 &dcesrv_conn);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2415 nt_errstr(status)));
2416 stream_terminate_connection(srv_conn, nt_errstr(status));
2417 return;
2420 dcesrv_conn->transport.private_data = srv_conn;
2421 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2423 TALLOC_FREE(srv_conn->event.fde);
2425 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2426 if (!dcesrv_conn->send_queue) {
2427 status = NT_STATUS_NO_MEMORY;
2428 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2429 nt_errstr(status)));
2430 stream_terminate_connection(srv_conn, nt_errstr(status));
2431 return;
2434 if (transport == NCACN_NP) {
2435 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2436 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2437 &srv_conn->tstream);
2438 } else {
2439 ret = tstream_bsd_existing_socket(dcesrv_conn,
2440 socket_get_fd(srv_conn->socket),
2441 &dcesrv_conn->stream);
2442 if (ret == -1) {
2443 status = map_nt_error_from_unix_common(errno);
2444 DEBUG(0, ("dcesrv_sock_accept: "
2445 "failed to setup tstream: %s\n",
2446 nt_errstr(status)));
2447 stream_terminate_connection(srv_conn, nt_errstr(status));
2448 return;
2450 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2453 dcesrv_conn->local_address = srv_conn->local_address;
2454 dcesrv_conn->remote_address = srv_conn->remote_address;
2456 if (transport == NCALRPC) {
2457 uid_t uid;
2458 gid_t gid;
2459 int sock_fd;
2461 sock_fd = socket_get_fd(srv_conn->socket);
2462 if (sock_fd == -1) {
2463 stream_terminate_connection(
2464 srv_conn, "socket_get_fd failed\n");
2465 return;
2468 ret = getpeereid(sock_fd, &uid, &gid);
2469 if (ret == -1) {
2470 status = map_nt_error_from_unix_common(errno);
2471 DEBUG(0, ("dcesrv_sock_accept: "
2472 "getpeereid() failed for NCALRPC: %s\n",
2473 nt_errstr(status)));
2474 stream_terminate_connection(srv_conn, nt_errstr(status));
2475 return;
2477 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2478 struct tsocket_address *r = NULL;
2480 ret = tsocket_address_unix_from_path(dcesrv_conn,
2481 "/root/ncalrpc_as_system",
2482 &r);
2483 if (ret == -1) {
2484 status = map_nt_error_from_unix_common(errno);
2485 DEBUG(0, ("dcesrv_sock_accept: "
2486 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2487 nt_errstr(status)));
2488 stream_terminate_connection(srv_conn, nt_errstr(status));
2489 return;
2491 dcesrv_conn->remote_address = r;
2495 srv_conn->private_data = dcesrv_conn;
2497 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2499 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2500 dcesrv_conn->event_ctx,
2501 dcesrv_conn->stream);
2502 if (!subreq) {
2503 status = NT_STATUS_NO_MEMORY;
2504 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2505 nt_errstr(status)));
2506 stream_terminate_connection(srv_conn, nt_errstr(status));
2507 return;
2509 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2511 return;
2514 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2516 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2518 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2519 struct dcesrv_connection);
2520 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2521 struct ncacn_packet *pkt;
2522 DATA_BLOB buffer;
2523 NTSTATUS status;
2525 if (dce_conn->terminate) {
2527 * if the current connection is broken
2528 * we need to clean it up before any other connection
2530 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2531 dcesrv_cleanup_broken_connections(dce_ctx);
2532 return;
2535 dcesrv_cleanup_broken_connections(dce_ctx);
2537 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2538 &pkt, &buffer);
2539 TALLOC_FREE(subreq);
2540 if (!NT_STATUS_IS_OK(status)) {
2541 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2542 return;
2545 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2546 if (!NT_STATUS_IS_OK(status)) {
2547 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2548 return;
2552 * This is used to block the connection during
2553 * pending authentication.
2555 if (dce_conn->wait_send != NULL) {
2556 subreq = dce_conn->wait_send(dce_conn,
2557 dce_conn->event_ctx,
2558 dce_conn->wait_private);
2559 if (!subreq) {
2560 status = NT_STATUS_NO_MEMORY;
2561 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2562 return;
2564 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2565 return;
2568 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2569 dce_conn->event_ctx,
2570 dce_conn->stream);
2571 if (!subreq) {
2572 status = NT_STATUS_NO_MEMORY;
2573 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2574 return;
2576 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2579 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2581 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2582 struct dcesrv_connection);
2583 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2584 NTSTATUS status;
2586 if (dce_conn->terminate) {
2588 * if the current connection is broken
2589 * we need to clean it up before any other connection
2591 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2592 dcesrv_cleanup_broken_connections(dce_ctx);
2593 return;
2596 dcesrv_cleanup_broken_connections(dce_ctx);
2598 status = dce_conn->wait_recv(subreq);
2599 dce_conn->wait_send = NULL;
2600 dce_conn->wait_recv = NULL;
2601 dce_conn->wait_private = NULL;
2602 TALLOC_FREE(subreq);
2603 if (!NT_STATUS_IS_OK(status)) {
2604 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2605 return;
2608 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2609 dce_conn->event_ctx,
2610 dce_conn->stream);
2611 if (!subreq) {
2612 status = NT_STATUS_NO_MEMORY;
2613 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2614 return;
2616 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2619 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2621 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2622 struct dcesrv_connection);
2623 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2626 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2628 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2629 struct dcesrv_connection);
2630 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2634 static const struct stream_server_ops dcesrv_stream_ops = {
2635 .name = "rpc",
2636 .accept_connection = dcesrv_sock_accept,
2637 .recv_handler = dcesrv_sock_recv,
2638 .send_handler = dcesrv_sock_send,
2641 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2642 struct loadparm_context *lp_ctx,
2643 struct dcesrv_endpoint *e,
2644 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2646 struct dcesrv_socket_context *dcesrv_sock;
2647 uint16_t port = 1;
2648 NTSTATUS status;
2649 const char *endpoint;
2651 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2652 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2654 /* remember the endpoint of this socket */
2655 dcesrv_sock->endpoint = e;
2656 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2658 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2660 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2661 model_ops, &dcesrv_stream_ops,
2662 "unix", endpoint, &port,
2663 lpcfg_socket_options(lp_ctx),
2664 dcesrv_sock);
2665 if (!NT_STATUS_IS_OK(status)) {
2666 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2667 endpoint, nt_errstr(status)));
2670 return status;
2673 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2674 struct loadparm_context *lp_ctx,
2675 struct dcesrv_endpoint *e,
2676 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2678 struct dcesrv_socket_context *dcesrv_sock;
2679 uint16_t port = 1;
2680 char *full_path;
2681 NTSTATUS status;
2682 const char *endpoint;
2684 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2686 if (endpoint == NULL) {
2688 * No identifier specified: use DEFAULT.
2690 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2691 * no endpoint and let the epmapper worry about it.
2693 endpoint = "DEFAULT";
2694 status = dcerpc_binding_set_string_option(e->ep_description,
2695 "endpoint",
2696 endpoint);
2697 if (!NT_STATUS_IS_OK(status)) {
2698 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2699 nt_errstr(status)));
2700 return status;
2704 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2705 endpoint);
2707 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2708 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2710 /* remember the endpoint of this socket */
2711 dcesrv_sock->endpoint = e;
2712 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2714 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2715 model_ops, &dcesrv_stream_ops,
2716 "unix", full_path, &port,
2717 lpcfg_socket_options(lp_ctx),
2718 dcesrv_sock);
2719 if (!NT_STATUS_IS_OK(status)) {
2720 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2721 endpoint, full_path, nt_errstr(status)));
2723 return status;
2726 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2727 struct loadparm_context *lp_ctx,
2728 struct dcesrv_endpoint *e,
2729 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2731 struct dcesrv_socket_context *dcesrv_sock;
2732 NTSTATUS status;
2733 const char *endpoint;
2735 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2736 if (endpoint == NULL) {
2737 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2738 return NT_STATUS_INVALID_PARAMETER;
2741 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2742 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2744 /* remember the endpoint of this socket */
2745 dcesrv_sock->endpoint = e;
2746 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2748 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2749 model_ops, &dcesrv_stream_ops,
2750 endpoint,
2751 dcesrv_sock);
2752 if (!NT_STATUS_IS_OK(status)) {
2753 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2754 endpoint, nt_errstr(status)));
2755 return status;
2758 return NT_STATUS_OK;
2762 add a socket address to the list of events, one event per dcerpc endpoint
2764 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2765 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2766 const char *address)
2768 struct dcesrv_socket_context *dcesrv_sock;
2769 uint16_t port = 0;
2770 NTSTATUS status;
2771 const char *endpoint;
2772 char port_str[6];
2774 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2775 if (endpoint != NULL) {
2776 port = atoi(endpoint);
2779 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2780 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2782 /* remember the endpoint of this socket */
2783 dcesrv_sock->endpoint = e;
2784 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2786 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2787 model_ops, &dcesrv_stream_ops,
2788 "ip", address, &port,
2789 lpcfg_socket_options(dce_ctx->lp_ctx),
2790 dcesrv_sock);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 struct dcesrv_if_list *iface;
2793 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2794 address, port));
2795 for (iface = e->interface_list; iface; iface = iface->next) {
2796 DEBUGADD(0, ("%s ", iface->iface.name));
2798 DEBUGADD(0, ("failed - %s",
2799 nt_errstr(status)));
2800 return status;
2803 snprintf(port_str, sizeof(port_str), "%u", port);
2805 status = dcerpc_binding_set_string_option(e->ep_description,
2806 "endpoint", port_str);
2807 if (!NT_STATUS_IS_OK(status)) {
2808 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2809 port_str, nt_errstr(status)));
2810 return status;
2811 } else {
2812 struct dcesrv_if_list *iface;
2813 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2814 address, port_str));
2815 for (iface = e->interface_list; iface; iface = iface->next) {
2816 DEBUGADD(4, ("%s ", iface->iface.name));
2818 DEBUGADD(4, ("\n"));
2821 return NT_STATUS_OK;
2824 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2826 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2827 struct loadparm_context *lp_ctx,
2828 struct dcesrv_endpoint *e,
2829 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2831 NTSTATUS status;
2833 /* Add TCP/IP sockets */
2834 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2835 int num_interfaces;
2836 int i;
2837 struct interface *ifaces;
2839 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2841 num_interfaces = iface_list_count(ifaces);
2842 for(i = 0; i < num_interfaces; i++) {
2843 const char *address = iface_list_n_ip(ifaces, i);
2844 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2845 NT_STATUS_NOT_OK_RETURN(status);
2847 } else {
2848 char **wcard;
2849 int i;
2850 int num_binds = 0;
2851 wcard = iface_list_wildcard(dce_ctx);
2852 NT_STATUS_HAVE_NO_MEMORY(wcard);
2853 for (i=0; wcard[i]; i++) {
2854 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2855 if (NT_STATUS_IS_OK(status)) {
2856 num_binds++;
2859 talloc_free(wcard);
2860 if (num_binds == 0) {
2861 return NT_STATUS_INVALID_PARAMETER_MIX;
2865 return NT_STATUS_OK;
2868 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2869 struct loadparm_context *lp_ctx,
2870 struct dcesrv_endpoint *e,
2871 struct tevent_context *event_ctx,
2872 const struct model_ops *model_ops)
2874 enum dcerpc_transport_t transport =
2875 dcerpc_binding_get_transport(e->ep_description);
2877 switch (transport) {
2878 case NCACN_UNIX_STREAM:
2879 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2881 case NCALRPC:
2882 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2884 case NCACN_IP_TCP:
2885 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2887 case NCACN_NP:
2888 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2890 default:
2891 return NT_STATUS_NOT_SUPPORTED;
2897 * retrieve credentials from a dce_call
2899 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2901 return dce_call->conn->auth_state.session_info->credentials;
2905 * returns true if this is an authenticated call
2907 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2909 enum security_user_level level;
2910 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2911 return level >= SECURITY_USER;
2915 * retrieve account_name for a dce_call
2917 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2919 return dce_call->context->conn->auth_state.session_info->info->account_name;