ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / rpc_server / dcerpc_server.c
blobe701503b4586432d5252bb2745a946b7dd790ead
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;
79 dcesrv_assoc_group_common_destructor(assoc_group);
81 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
82 if (ret != 0) {
83 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
84 assoc_group->id));
86 SMB_ASSERT(assoc_group->dce_ctx->assoc_groups_num > 0);
87 assoc_group->dce_ctx->assoc_groups_num -= 1;
88 return 0;
92 allocate a new association group
94 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(struct dcesrv_connection *conn)
96 struct dcesrv_context *dce_ctx = conn->dce_ctx;
97 const struct dcesrv_endpoint *endpoint = conn->endpoint;
98 enum dcerpc_transport_t transport =
99 dcerpc_binding_get_transport(endpoint->ep_description);
100 struct dcesrv_assoc_group *assoc_group;
101 int id;
103 assoc_group = talloc_zero(conn, struct dcesrv_assoc_group);
104 if (assoc_group == NULL) {
105 return NULL;
108 id = idr_get_new_random(
109 dce_ctx->assoc_groups_idr, assoc_group, 1, UINT16_MAX);
110 if (id == -1) {
111 talloc_free(assoc_group);
112 DEBUG(0,(__location__ ": Out of association groups!\n"));
113 return NULL;
116 assoc_group->transport = transport;
117 assoc_group->id = id;
118 assoc_group->dce_ctx = dce_ctx;
120 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
122 SMB_ASSERT(dce_ctx->assoc_groups_num < UINT16_MAX);
123 dce_ctx->assoc_groups_num += 1;
125 return assoc_group;
128 NTSTATUS dcesrv_assoc_group_find_s4(
129 struct dcesrv_call_state *call,
130 void *private_data)
133 if provided, check the assoc_group is valid
135 if (call->pkt.u.bind.assoc_group_id != 0) {
136 call->conn->assoc_group =
137 dcesrv_assoc_group_reference(call->conn,
138 call->pkt.u.bind.assoc_group_id);
139 } else {
140 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn);
144 * The NETLOGON server does not use handles and so
145 * there is no need to support association groups, but
146 * we need to give back a number regardless.
148 * We have to do this when it is not run as a single process,
149 * because then it can't see the other valid association
150 * groups. We handle this generically for all endpoints not
151 * running in single process mode.
153 * We know which endpoint we are on even before checking the
154 * iface UUID, so for simplicity we enforce the same policy
155 * for all interfaces on the endpoint.
157 * This means that where NETLOGON
158 * shares an endpoint (such as ncalrpc or if 'lsa over
159 * netlogon' is set) we will still check association groups.
163 if (call->conn->assoc_group == NULL &&
164 !call->conn->endpoint->use_single_process) {
165 call->conn->assoc_group
166 = dcesrv_assoc_group_new(call->conn);
169 if (call->conn->assoc_group == NULL) {
170 /* TODO Return correct status */
171 return NT_STATUS_UNSUCCESSFUL;
174 return NT_STATUS_OK;
177 void dcerpc_server_init(struct loadparm_context *lp_ctx)
179 static bool initialized;
180 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
181 STATIC_dcerpc_server_MODULES_PROTO;
182 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
183 init_module_fn *shared_init;
185 if (initialized) {
186 return;
188 initialized = true;
190 shared_init = load_samba_modules(NULL, "dcerpc_server");
192 run_init_functions(NULL, static_init);
193 run_init_functions(NULL, shared_init);
195 talloc_free(shared_init);
198 struct dcesrv_socket_context {
199 const struct dcesrv_endpoint *endpoint;
200 struct dcesrv_context *dcesrv_ctx;
203 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
205 NTSTATUS status;
206 struct dcesrv_socket_context *dcesrv_sock =
207 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
208 enum dcerpc_transport_t transport =
209 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
210 struct dcesrv_connection *dcesrv_conn = NULL;
211 int ret;
212 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
214 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
216 if (!srv_conn->session_info) {
217 status = auth_anonymous_session_info(srv_conn,
218 lp_ctx,
219 &srv_conn->session_info);
220 if (!NT_STATUS_IS_OK(status)) {
221 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
222 nt_errstr(status)));
223 stream_terminate_connection(srv_conn, nt_errstr(status));
224 return;
229 * This fills in dcesrv_conn->endpoint with the endpoint
230 * associated with the socket. From this point on we know
231 * which (group of) services we are handling, but not the
232 * specific interface.
235 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
236 srv_conn,
237 dcesrv_sock->endpoint,
238 srv_conn->session_info,
239 srv_conn->event.ctx,
240 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
241 &dcesrv_conn);
242 if (!NT_STATUS_IS_OK(status)) {
243 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
244 nt_errstr(status)));
245 stream_terminate_connection(srv_conn, nt_errstr(status));
246 return;
249 dcesrv_conn->transport.private_data = srv_conn;
250 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
251 dcesrv_conn->transport.terminate_connection = dcesrv_transport_terminate_connection_s4;
253 TALLOC_FREE(srv_conn->event.fde);
255 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
256 if (!dcesrv_conn->send_queue) {
257 status = NT_STATUS_NO_MEMORY;
258 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
259 nt_errstr(status)));
260 stream_terminate_connection(srv_conn, nt_errstr(status));
261 return;
264 if (transport == NCACN_NP) {
265 dcesrv_conn->stream = talloc_move(dcesrv_conn,
266 &srv_conn->tstream);
267 } else {
268 ret = tstream_bsd_existing_socket(dcesrv_conn,
269 socket_get_fd(srv_conn->socket),
270 &dcesrv_conn->stream);
271 if (ret == -1) {
272 status = map_nt_error_from_unix_common(errno);
273 DEBUG(0, ("dcesrv_sock_accept: "
274 "failed to setup tstream: %s\n",
275 nt_errstr(status)));
276 stream_terminate_connection(srv_conn, nt_errstr(status));
277 return;
279 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
280 /* as server we want to fail early */
281 tstream_bsd_fail_readv_first_error(dcesrv_conn->stream, true);
284 dcesrv_conn->local_address = srv_conn->local_address;
285 dcesrv_conn->remote_address = srv_conn->remote_address;
287 if (transport == NCALRPC) {
288 uid_t uid;
289 gid_t gid;
290 int sock_fd;
292 sock_fd = socket_get_fd(srv_conn->socket);
293 if (sock_fd == -1) {
294 stream_terminate_connection(
295 srv_conn, "socket_get_fd failed\n");
296 return;
299 ret = getpeereid(sock_fd, &uid, &gid);
300 if (ret == -1) {
301 status = map_nt_error_from_unix_common(errno);
302 DEBUG(0, ("dcesrv_sock_accept: "
303 "getpeereid() failed for NCALRPC: %s\n",
304 nt_errstr(status)));
305 stream_terminate_connection(srv_conn, nt_errstr(status));
306 return;
308 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
309 struct tsocket_address *r = NULL;
311 ret = tsocket_address_unix_from_path(dcesrv_conn,
312 AS_SYSTEM_MAGIC_PATH_TOKEN,
313 &r);
314 if (ret == -1) {
315 status = map_nt_error_from_unix_common(errno);
316 DEBUG(0, ("dcesrv_sock_accept: "
317 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
318 nt_errstr(status)));
319 stream_terminate_connection(srv_conn, nt_errstr(status));
320 return;
322 dcesrv_conn->remote_address = r;
326 srv_conn->private_data = dcesrv_conn;
328 status = dcesrv_connection_loop_start(dcesrv_conn);
329 if (!NT_STATUS_IS_OK(status)) {
330 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
331 nt_errstr(status)));
332 stream_terminate_connection(srv_conn, nt_errstr(status));
333 return;
336 return;
339 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
341 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
342 struct dcesrv_connection);
343 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
346 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
348 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
349 struct dcesrv_connection);
350 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
354 static const struct stream_server_ops dcesrv_stream_ops = {
355 .name = "rpc",
356 .accept_connection = dcesrv_sock_accept,
357 .recv_handler = dcesrv_sock_recv,
358 .send_handler = dcesrv_sock_send,
361 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
362 struct loadparm_context *lp_ctx,
363 struct dcesrv_endpoint *e,
364 struct tevent_context *event_ctx,
365 const struct model_ops *model_ops,
366 void *process_context)
368 struct dcesrv_socket_context *dcesrv_sock;
369 uint16_t port = 1;
370 NTSTATUS status;
371 const char *endpoint;
373 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
374 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
376 /* remember the endpoint of this socket */
377 dcesrv_sock->endpoint = e;
378 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
380 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
382 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
383 model_ops, &dcesrv_stream_ops,
384 "unix", endpoint, &port,
385 lpcfg_socket_options(lp_ctx),
386 dcesrv_sock, process_context);
387 if (!NT_STATUS_IS_OK(status)) {
388 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
389 endpoint, nt_errstr(status)));
392 return status;
395 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
396 struct loadparm_context *lp_ctx,
397 struct dcesrv_endpoint *e,
398 struct tevent_context *event_ctx,
399 const struct model_ops *model_ops,
400 void *process_context)
402 struct dcesrv_socket_context *dcesrv_sock;
403 uint16_t port = 1;
404 char *full_path;
405 NTSTATUS status;
406 const char *endpoint;
408 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
410 if (endpoint == NULL) {
412 * No identifier specified: use DEFAULT.
414 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
415 * no endpoint and let the epmapper worry about it.
417 endpoint = "DEFAULT";
418 status = dcerpc_binding_set_string_option(e->ep_description,
419 "endpoint",
420 endpoint);
421 if (!NT_STATUS_IS_OK(status)) {
422 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
423 nt_errstr(status)));
424 return status;
428 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
429 endpoint);
431 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
432 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
434 /* remember the endpoint of this socket */
435 dcesrv_sock->endpoint = e;
436 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
438 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
439 model_ops, &dcesrv_stream_ops,
440 "unix", full_path, &port,
441 lpcfg_socket_options(lp_ctx),
442 dcesrv_sock, process_context);
443 if (!NT_STATUS_IS_OK(status)) {
444 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
445 endpoint, full_path, nt_errstr(status)));
447 return status;
450 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
451 struct loadparm_context *lp_ctx,
452 struct dcesrv_endpoint *e,
453 struct tevent_context *event_ctx,
454 const struct model_ops *model_ops,
455 void *process_context)
457 struct dcesrv_socket_context *dcesrv_sock;
458 NTSTATUS status;
459 const char *endpoint;
461 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
462 if (endpoint == NULL) {
463 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
464 return NT_STATUS_INVALID_PARAMETER;
467 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
468 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
470 /* remember the endpoint of this socket */
471 dcesrv_sock->endpoint = e;
472 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
474 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
475 model_ops, &dcesrv_stream_ops,
476 endpoint,
477 dcesrv_sock, process_context);
478 if (!NT_STATUS_IS_OK(status)) {
479 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
480 endpoint, nt_errstr(status)));
481 return status;
484 return NT_STATUS_OK;
488 add a socket address to the list of events, one event per dcerpc endpoint
490 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
491 struct dcesrv_endpoint *e,
492 struct tevent_context *event_ctx,
493 const struct model_ops *model_ops,
494 const char *address,
495 void *process_context)
497 struct dcesrv_socket_context *dcesrv_sock;
498 uint16_t port = 0;
499 NTSTATUS status;
500 const char *endpoint;
501 char port_str[6];
503 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
504 if (endpoint != NULL) {
505 port = atoi(endpoint);
508 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
509 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
511 /* remember the endpoint of this socket */
512 dcesrv_sock->endpoint = e;
513 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
515 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
516 model_ops, &dcesrv_stream_ops,
517 "ip", address, &port,
518 lpcfg_socket_options(dce_ctx->lp_ctx),
519 dcesrv_sock, process_context);
520 if (!NT_STATUS_IS_OK(status)) {
521 struct dcesrv_if_list *iface;
522 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
523 address, port));
524 for (iface = e->interface_list; iface; iface = iface->next) {
525 DEBUGADD(0, ("%s ", iface->iface->name));
527 DEBUGADD(0, ("failed - %s\n",
528 nt_errstr(status)));
529 return status;
532 snprintf(port_str, sizeof(port_str), "%u", port);
534 status = dcerpc_binding_set_string_option(e->ep_description,
535 "endpoint", port_str);
536 if (!NT_STATUS_IS_OK(status)) {
537 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
538 port_str, nt_errstr(status)));
539 return status;
540 } else {
541 struct dcesrv_if_list *iface;
542 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
543 address, port_str));
544 for (iface = e->interface_list; iface; iface = iface->next) {
545 DEBUGADD(4, ("%s ", iface->iface->name));
547 DEBUGADD(4, ("\n"));
550 return NT_STATUS_OK;
553 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
555 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
556 struct loadparm_context *lp_ctx,
557 struct dcesrv_endpoint *e,
558 struct tevent_context *event_ctx,
559 const struct model_ops *model_ops,
560 void *process_context)
562 NTSTATUS status;
564 /* Add TCP/IP sockets */
565 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
566 int num_interfaces;
567 int i;
568 struct interface *ifaces;
570 load_interface_list(dce_ctx, lp_ctx, &ifaces);
572 num_interfaces = iface_list_count(ifaces);
573 for(i = 0; i < num_interfaces; i++) {
574 const char *address = iface_list_n_ip(ifaces, i);
575 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
576 model_ops, address,
577 process_context);
578 NT_STATUS_NOT_OK_RETURN(status);
580 } else {
581 char **wcard;
582 size_t i;
583 size_t num_binds = 0;
584 wcard = iface_list_wildcard(dce_ctx);
585 NT_STATUS_HAVE_NO_MEMORY(wcard);
586 for (i=0; wcard[i]; i++) {
587 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
588 model_ops, wcard[i],
589 process_context);
590 if (NT_STATUS_IS_OK(status)) {
591 num_binds++;
594 talloc_free(wcard);
595 if (num_binds == 0) {
596 return NT_STATUS_INVALID_PARAMETER_MIX;
600 return NT_STATUS_OK;
603 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
604 struct loadparm_context *lp_ctx,
605 struct dcesrv_endpoint *e,
606 struct tevent_context *event_ctx,
607 const struct model_ops *model_ops,
608 void *process_context)
610 enum dcerpc_transport_t transport =
611 dcerpc_binding_get_transport(e->ep_description);
613 switch (transport) {
614 case NCACN_UNIX_STREAM:
615 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
616 model_ops, process_context);
618 case NCALRPC:
619 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
620 model_ops, process_context);
622 case NCACN_IP_TCP:
623 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
624 model_ops, process_context);
626 case NCACN_NP:
627 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
628 model_ops, process_context);
630 default:
631 return NT_STATUS_NOT_SUPPORTED;
635 _PUBLIC_ struct imessaging_context *dcesrv_imessaging_context(
636 struct dcesrv_connection *conn)
638 struct stream_connection *srv_conn =
639 talloc_get_type_abort(conn->transport.private_data,
640 struct stream_connection);
641 return srv_conn->msg_ctx;
644 _PUBLIC_ struct server_id dcesrv_server_id(struct dcesrv_connection *conn)
646 struct stream_connection *srv_conn =
647 talloc_get_type_abort(conn->transport.private_data,
648 struct stream_connection);
649 return srv_conn->server_id;
652 void log_successful_dcesrv_authz_event(
653 struct dcesrv_call_state *call,
654 void *private_data)
656 struct dcesrv_auth *auth = call->auth_state;
657 enum dcerpc_transport_t transport =
658 dcerpc_binding_get_transport(call->conn->endpoint->ep_description);
659 struct imessaging_context *imsg_ctx =
660 dcesrv_imessaging_context(call->conn);
661 const char *auth_type = derpc_transport_string_by_transport(transport);
662 const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
664 if (transport == NCACN_NP) {
665 transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
669 * Log the authorization to this RPC interface. This
670 * covered ncacn_np pass-through auth, and anonymous
671 * DCE/RPC (eg epmapper, netlogon etc)
673 log_successful_authz_event(imsg_ctx,
674 call->conn->dce_ctx->lp_ctx,
675 call->conn->remote_address,
676 call->conn->local_address,
677 "DCE/RPC",
678 auth_type,
679 transport_protection,
680 auth->session_info,
681 NULL /* client_audit_info */,
682 NULL /* server_audit_info */);
684 auth->auth_audited = true;
687 NTSTATUS dcesrv_gensec_prepare(
688 TALLOC_CTX *mem_ctx,
689 struct dcesrv_call_state *call,
690 struct gensec_security **out,
691 void *private_data)
693 struct cli_credentials *server_creds = NULL;
694 struct imessaging_context *imsg_ctx =
695 dcesrv_imessaging_context(call->conn);
696 bool ok;
698 server_creds = cli_credentials_init_server(call->auth_state,
699 call->conn->dce_ctx->lp_ctx);
700 if (server_creds == NULL) {
701 DEBUG(1, ("Failed to init server credentials\n"));
702 return NT_STATUS_NO_MEMORY;
704 /* This is required for ncalrpc_as_system. */
705 ok = cli_credentials_set_kerberos_state(server_creds,
706 CRED_USE_KERBEROS_DESIRED,
707 CRED_SPECIFIED);
708 if (!ok) {
709 DBG_WARNING("Failed to set kerberos state\n");
710 return NT_STATUS_INTERNAL_ERROR;
713 return samba_server_gensec_start(mem_ctx,
714 call->event_ctx,
715 imsg_ctx,
716 call->conn->dce_ctx->lp_ctx,
717 server_creds,
718 NULL,
719 out);
722 void dcesrv_transport_terminate_connection_s4(struct dcesrv_connection *dce_conn,
723 const char *reason)
725 struct stream_connection *srv_conn =
726 talloc_get_type_abort(dce_conn->transport.private_data,
727 struct stream_connection);
728 stream_terminate_connection(srv_conn, reason);