auth4: Fix CID 1034877 Resource leak
[Samba.git] / source4 / rpc_server / dcerpc_server.c
blobe072cd20f95ae542febc076d99d040b54e34a799
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 "auth/credentials/credentials.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "param/param.h"
30 #include "samba/service_stream.h"
31 #include "lib/tsocket/tsocket.h"
32 #include "lib/socket/socket.h"
33 #include "samba/process_model.h"
34 #include "lib/util/samba_modules.h"
35 #include "lib/util/tevent_ntstatus.h"
36 #include "lib/util/idtree_random.h"
39 take a reference to an existing association group
41 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(struct dcesrv_connection *conn,
42 uint32_t id)
44 const struct dcesrv_endpoint *endpoint = conn->endpoint;
45 enum dcerpc_transport_t transport =
46 dcerpc_binding_get_transport(endpoint->ep_description);
47 struct dcesrv_assoc_group *assoc_group;
48 void *id_ptr = NULL;
50 /* find an association group given a assoc_group_id */
51 id_ptr = idr_find(conn->dce_ctx->assoc_groups_idr, id);
52 if (id_ptr == NULL) {
53 DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id);
54 return NULL;
56 assoc_group = talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
58 if (assoc_group->transport != transport) {
59 const char *at =
60 derpc_transport_string_by_transport(
61 assoc_group->transport);
62 const char *ct =
63 derpc_transport_string_by_transport(
64 transport);
66 DBG_NOTICE("assoc_group 0x%08x (transport %s) "
67 "is not available on transport %s\n",
68 id, at, ct);
69 return NULL;
72 return talloc_reference(conn, assoc_group);
75 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
77 int ret;
78 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
79 if (ret != 0) {
80 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
81 assoc_group->id));
83 SMB_ASSERT(assoc_group->dce_ctx->assoc_groups_num > 0);
84 assoc_group->dce_ctx->assoc_groups_num -= 1;
85 return 0;
89 allocate a new association group
91 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(struct dcesrv_connection *conn)
93 struct dcesrv_context *dce_ctx = conn->dce_ctx;
94 const struct dcesrv_endpoint *endpoint = conn->endpoint;
95 enum dcerpc_transport_t transport =
96 dcerpc_binding_get_transport(endpoint->ep_description);
97 struct dcesrv_assoc_group *assoc_group;
98 int id;
100 assoc_group = talloc_zero(conn, struct dcesrv_assoc_group);
101 if (assoc_group == NULL) {
102 return NULL;
105 id = idr_get_new_random(
106 dce_ctx->assoc_groups_idr, assoc_group, 1, 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->transport = transport;
114 assoc_group->id = id;
115 assoc_group->dce_ctx = dce_ctx;
117 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
119 SMB_ASSERT(dce_ctx->assoc_groups_num < UINT16_MAX);
120 dce_ctx->assoc_groups_num += 1;
122 return assoc_group;
125 NTSTATUS dcesrv_assoc_group_find_s4(
126 struct dcesrv_call_state *call,
127 void *private_data)
130 if provided, check the assoc_group is valid
132 if (call->pkt.u.bind.assoc_group_id != 0) {
133 call->conn->assoc_group =
134 dcesrv_assoc_group_reference(call->conn,
135 call->pkt.u.bind.assoc_group_id);
136 } else {
137 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn);
141 * The NETLOGON server does not use handles and so
142 * there is no need to support association groups, but
143 * we need to give back a number regardless.
145 * We have to do this when it is not run as a single process,
146 * because then it can't see the other valid association
147 * groups. We handle this generically for all endpoints not
148 * running in single process mode.
150 * We know which endpoint we are on even before checking the
151 * iface UUID, so for simplicity we enforce the same policy
152 * for all interfaces on the endpoint.
154 * This means that where NETLOGON
155 * shares an endpoint (such as ncalrpc or if 'lsa over
156 * netlogon' is set) we will still check association groups.
160 if (call->conn->assoc_group == NULL &&
161 !call->conn->endpoint->use_single_process) {
162 call->conn->assoc_group
163 = dcesrv_assoc_group_new(call->conn);
166 if (call->conn->assoc_group == NULL) {
167 /* TODO Return correct status */
168 return NT_STATUS_UNSUCCESSFUL;
171 return NT_STATUS_OK;
174 void dcerpc_server_init(struct loadparm_context *lp_ctx)
176 static bool initialized;
177 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
178 STATIC_dcerpc_server_MODULES_PROTO;
179 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
180 init_module_fn *shared_init;
182 if (initialized) {
183 return;
185 initialized = true;
187 shared_init = load_samba_modules(NULL, "dcerpc_server");
189 run_init_functions(NULL, static_init);
190 run_init_functions(NULL, shared_init);
192 talloc_free(shared_init);
195 struct dcesrv_socket_context {
196 const struct dcesrv_endpoint *endpoint;
197 struct dcesrv_context *dcesrv_ctx;
200 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
202 NTSTATUS status;
203 struct dcesrv_socket_context *dcesrv_sock =
204 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
205 enum dcerpc_transport_t transport =
206 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
207 struct dcesrv_connection *dcesrv_conn = NULL;
208 int ret;
209 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
211 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
213 if (!srv_conn->session_info) {
214 status = auth_anonymous_session_info(srv_conn,
215 lp_ctx,
216 &srv_conn->session_info);
217 if (!NT_STATUS_IS_OK(status)) {
218 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
219 nt_errstr(status)));
220 stream_terminate_connection(srv_conn, nt_errstr(status));
221 return;
226 * This fills in dcesrv_conn->endpoint with the endpoint
227 * associated with the socket. From this point on we know
228 * which (group of) services we are handling, but not the
229 * specific interface.
232 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
233 srv_conn,
234 dcesrv_sock->endpoint,
235 srv_conn->session_info,
236 srv_conn->event.ctx,
237 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
238 &dcesrv_conn);
239 if (!NT_STATUS_IS_OK(status)) {
240 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
241 nt_errstr(status)));
242 stream_terminate_connection(srv_conn, nt_errstr(status));
243 return;
246 dcesrv_conn->transport.private_data = srv_conn;
247 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
248 dcesrv_conn->transport.terminate_connection = dcesrv_transport_terminate_connection_s4;
250 TALLOC_FREE(srv_conn->event.fde);
252 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
253 if (!dcesrv_conn->send_queue) {
254 status = NT_STATUS_NO_MEMORY;
255 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
256 nt_errstr(status)));
257 stream_terminate_connection(srv_conn, nt_errstr(status));
258 return;
261 if (transport == NCACN_NP) {
262 dcesrv_conn->stream = talloc_move(dcesrv_conn,
263 &srv_conn->tstream);
264 } else {
265 ret = tstream_bsd_existing_socket(dcesrv_conn,
266 socket_get_fd(srv_conn->socket),
267 &dcesrv_conn->stream);
268 if (ret == -1) {
269 status = map_nt_error_from_unix_common(errno);
270 DEBUG(0, ("dcesrv_sock_accept: "
271 "failed to setup tstream: %s\n",
272 nt_errstr(status)));
273 stream_terminate_connection(srv_conn, nt_errstr(status));
274 return;
276 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
277 /* as server we want to fail early */
278 tstream_bsd_fail_readv_first_error(dcesrv_conn->stream, true);
281 dcesrv_conn->local_address = srv_conn->local_address;
282 dcesrv_conn->remote_address = srv_conn->remote_address;
284 if (transport == NCALRPC) {
285 uid_t uid;
286 gid_t gid;
287 int sock_fd;
289 sock_fd = socket_get_fd(srv_conn->socket);
290 if (sock_fd == -1) {
291 stream_terminate_connection(
292 srv_conn, "socket_get_fd failed\n");
293 return;
296 ret = getpeereid(sock_fd, &uid, &gid);
297 if (ret == -1) {
298 status = map_nt_error_from_unix_common(errno);
299 DEBUG(0, ("dcesrv_sock_accept: "
300 "getpeereid() failed for NCALRPC: %s\n",
301 nt_errstr(status)));
302 stream_terminate_connection(srv_conn, nt_errstr(status));
303 return;
305 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
306 struct tsocket_address *r = NULL;
308 ret = tsocket_address_unix_from_path(dcesrv_conn,
309 AS_SYSTEM_MAGIC_PATH_TOKEN,
310 &r);
311 if (ret == -1) {
312 status = map_nt_error_from_unix_common(errno);
313 DEBUG(0, ("dcesrv_sock_accept: "
314 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
315 nt_errstr(status)));
316 stream_terminate_connection(srv_conn, nt_errstr(status));
317 return;
319 dcesrv_conn->remote_address = r;
323 srv_conn->private_data = dcesrv_conn;
325 status = dcesrv_connection_loop_start(dcesrv_conn);
326 if (!NT_STATUS_IS_OK(status)) {
327 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
328 nt_errstr(status)));
329 stream_terminate_connection(srv_conn, nt_errstr(status));
330 return;
333 return;
336 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
338 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
339 struct dcesrv_connection);
340 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
343 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
345 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
346 struct dcesrv_connection);
347 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
351 static const struct stream_server_ops dcesrv_stream_ops = {
352 .name = "rpc",
353 .accept_connection = dcesrv_sock_accept,
354 .recv_handler = dcesrv_sock_recv,
355 .send_handler = dcesrv_sock_send,
358 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
359 struct loadparm_context *lp_ctx,
360 struct dcesrv_endpoint *e,
361 struct tevent_context *event_ctx,
362 const struct model_ops *model_ops,
363 void *process_context)
365 struct dcesrv_socket_context *dcesrv_sock;
366 uint16_t port = 1;
367 NTSTATUS status;
368 const char *endpoint;
370 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
371 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
373 /* remember the endpoint of this socket */
374 dcesrv_sock->endpoint = e;
375 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
377 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
379 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
380 model_ops, &dcesrv_stream_ops,
381 "unix", endpoint, &port,
382 lpcfg_socket_options(lp_ctx),
383 dcesrv_sock, process_context);
384 if (!NT_STATUS_IS_OK(status)) {
385 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
386 endpoint, nt_errstr(status)));
389 return status;
392 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
393 struct loadparm_context *lp_ctx,
394 struct dcesrv_endpoint *e,
395 struct tevent_context *event_ctx,
396 const struct model_ops *model_ops,
397 void *process_context)
399 struct dcesrv_socket_context *dcesrv_sock;
400 uint16_t port = 1;
401 char *full_path;
402 NTSTATUS status;
403 const char *endpoint;
405 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
407 if (endpoint == NULL) {
409 * No identifier specified: use DEFAULT.
411 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
412 * no endpoint and let the epmapper worry about it.
414 endpoint = "DEFAULT";
415 status = dcerpc_binding_set_string_option(e->ep_description,
416 "endpoint",
417 endpoint);
418 if (!NT_STATUS_IS_OK(status)) {
419 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
420 nt_errstr(status)));
421 return status;
425 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
426 endpoint);
428 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
429 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
431 /* remember the endpoint of this socket */
432 dcesrv_sock->endpoint = e;
433 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
435 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
436 model_ops, &dcesrv_stream_ops,
437 "unix", full_path, &port,
438 lpcfg_socket_options(lp_ctx),
439 dcesrv_sock, process_context);
440 if (!NT_STATUS_IS_OK(status)) {
441 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
442 endpoint, full_path, nt_errstr(status)));
444 return status;
447 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
448 struct loadparm_context *lp_ctx,
449 struct dcesrv_endpoint *e,
450 struct tevent_context *event_ctx,
451 const struct model_ops *model_ops,
452 void *process_context)
454 struct dcesrv_socket_context *dcesrv_sock;
455 NTSTATUS status;
456 const char *endpoint;
458 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
459 if (endpoint == NULL) {
460 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
461 return NT_STATUS_INVALID_PARAMETER;
464 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
465 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
467 /* remember the endpoint of this socket */
468 dcesrv_sock->endpoint = e;
469 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
471 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
472 model_ops, &dcesrv_stream_ops,
473 endpoint,
474 dcesrv_sock, process_context);
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
477 endpoint, nt_errstr(status)));
478 return status;
481 return NT_STATUS_OK;
485 add a socket address to the list of events, one event per dcerpc endpoint
487 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
488 struct dcesrv_endpoint *e,
489 struct tevent_context *event_ctx,
490 const struct model_ops *model_ops,
491 const char *address,
492 void *process_context)
494 struct dcesrv_socket_context *dcesrv_sock;
495 uint16_t port = 0;
496 NTSTATUS status;
497 const char *endpoint;
498 char port_str[6];
500 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
501 if (endpoint != NULL) {
502 port = atoi(endpoint);
505 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
506 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
508 /* remember the endpoint of this socket */
509 dcesrv_sock->endpoint = e;
510 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
512 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
513 model_ops, &dcesrv_stream_ops,
514 "ip", address, &port,
515 lpcfg_socket_options(dce_ctx->lp_ctx),
516 dcesrv_sock, process_context);
517 if (!NT_STATUS_IS_OK(status)) {
518 struct dcesrv_if_list *iface;
519 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
520 address, port));
521 for (iface = e->interface_list; iface; iface = iface->next) {
522 DEBUGADD(0, ("%s ", iface->iface->name));
524 DEBUGADD(0, ("failed - %s\n",
525 nt_errstr(status)));
526 return status;
529 snprintf(port_str, sizeof(port_str), "%u", port);
531 status = dcerpc_binding_set_string_option(e->ep_description,
532 "endpoint", port_str);
533 if (!NT_STATUS_IS_OK(status)) {
534 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
535 port_str, nt_errstr(status)));
536 return status;
537 } else {
538 struct dcesrv_if_list *iface;
539 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
540 address, port_str));
541 for (iface = e->interface_list; iface; iface = iface->next) {
542 DEBUGADD(4, ("%s ", iface->iface->name));
544 DEBUGADD(4, ("\n"));
547 return NT_STATUS_OK;
550 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
552 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
553 struct loadparm_context *lp_ctx,
554 struct dcesrv_endpoint *e,
555 struct tevent_context *event_ctx,
556 const struct model_ops *model_ops,
557 void *process_context)
559 NTSTATUS status;
561 /* Add TCP/IP sockets */
562 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
563 int num_interfaces;
564 int i;
565 struct interface *ifaces;
567 load_interface_list(dce_ctx, lp_ctx, &ifaces);
569 num_interfaces = iface_list_count(ifaces);
570 for(i = 0; i < num_interfaces; i++) {
571 const char *address = iface_list_n_ip(ifaces, i);
572 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
573 model_ops, address,
574 process_context);
575 NT_STATUS_NOT_OK_RETURN(status);
577 } else {
578 char **wcard;
579 size_t i;
580 size_t num_binds = 0;
581 wcard = iface_list_wildcard(dce_ctx);
582 NT_STATUS_HAVE_NO_MEMORY(wcard);
583 for (i=0; wcard[i]; i++) {
584 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
585 model_ops, wcard[i],
586 process_context);
587 if (NT_STATUS_IS_OK(status)) {
588 num_binds++;
591 talloc_free(wcard);
592 if (num_binds == 0) {
593 return NT_STATUS_INVALID_PARAMETER_MIX;
597 return NT_STATUS_OK;
600 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
601 struct loadparm_context *lp_ctx,
602 struct dcesrv_endpoint *e,
603 struct tevent_context *event_ctx,
604 const struct model_ops *model_ops,
605 void *process_context)
607 enum dcerpc_transport_t transport =
608 dcerpc_binding_get_transport(e->ep_description);
610 switch (transport) {
611 case NCACN_UNIX_STREAM:
612 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
613 model_ops, process_context);
615 case NCALRPC:
616 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
617 model_ops, process_context);
619 case NCACN_IP_TCP:
620 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
621 model_ops, process_context);
623 case NCACN_NP:
624 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
625 model_ops, process_context);
627 default:
628 return NT_STATUS_NOT_SUPPORTED;
632 _PUBLIC_ struct imessaging_context *dcesrv_imessaging_context(
633 struct dcesrv_connection *conn)
635 struct stream_connection *srv_conn =
636 talloc_get_type_abort(conn->transport.private_data,
637 struct stream_connection);
638 return srv_conn->msg_ctx;
641 _PUBLIC_ struct server_id dcesrv_server_id(struct dcesrv_connection *conn)
643 struct stream_connection *srv_conn =
644 talloc_get_type_abort(conn->transport.private_data,
645 struct stream_connection);
646 return srv_conn->server_id;
649 void log_successful_dcesrv_authz_event(
650 struct dcesrv_call_state *call,
651 void *private_data)
653 struct dcesrv_auth *auth = call->auth_state;
654 enum dcerpc_transport_t transport =
655 dcerpc_binding_get_transport(call->conn->endpoint->ep_description);
656 struct imessaging_context *imsg_ctx =
657 dcesrv_imessaging_context(call->conn);
658 const char *auth_type = derpc_transport_string_by_transport(transport);
659 const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
661 if (transport == NCACN_NP) {
662 transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
666 * Log the authorization to this RPC interface. This
667 * covered ncacn_np pass-through auth, and anonymous
668 * DCE/RPC (eg epmapper, netlogon etc)
670 log_successful_authz_event(imsg_ctx,
671 call->conn->dce_ctx->lp_ctx,
672 call->conn->remote_address,
673 call->conn->local_address,
674 "DCE/RPC",
675 auth_type,
676 transport_protection,
677 auth->session_info,
678 NULL /* client_audit_info */,
679 NULL /* server_audit_info */);
681 auth->auth_audited = true;
684 NTSTATUS dcesrv_gensec_prepare(
685 TALLOC_CTX *mem_ctx,
686 struct dcesrv_call_state *call,
687 struct gensec_security **out,
688 void *private_data)
690 struct cli_credentials *server_creds = NULL;
691 struct imessaging_context *imsg_ctx =
692 dcesrv_imessaging_context(call->conn);
693 bool ok;
695 server_creds = cli_credentials_init_server(call->auth_state,
696 call->conn->dce_ctx->lp_ctx);
697 if (server_creds == NULL) {
698 DEBUG(1, ("Failed to init server credentials\n"));
699 return NT_STATUS_NO_MEMORY;
701 /* This is required for ncalrpc_as_system. */
702 ok = cli_credentials_set_kerberos_state(server_creds,
703 CRED_USE_KERBEROS_DESIRED,
704 CRED_SPECIFIED);
705 if (!ok) {
706 DBG_WARNING("Failed to set kerberos state\n");
707 return NT_STATUS_INTERNAL_ERROR;
710 return samba_server_gensec_start(mem_ctx,
711 call->event_ctx,
712 imsg_ctx,
713 call->conn->dce_ctx->lp_ctx,
714 server_creds,
715 NULL,
716 out);
719 void dcesrv_transport_terminate_connection_s4(struct dcesrv_connection *dce_conn,
720 const char *reason)
722 struct stream_connection *srv_conn =
723 talloc_get_type_abort(dce_conn->transport.private_data,
724 struct stream_connection);
725 stream_terminate_connection(srv_conn, reason);