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/>.
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
,
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
;
50 /* find an association group given a assoc_group_id */
51 id_ptr
= idr_find(conn
->dce_ctx
->assoc_groups_idr
, id
);
53 DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id
);
56 assoc_group
= talloc_get_type_abort(id_ptr
, struct dcesrv_assoc_group
);
58 if (assoc_group
->transport
!= transport
) {
60 derpc_transport_string_by_transport(
61 assoc_group
->transport
);
63 derpc_transport_string_by_transport(
66 DBG_NOTICE("assoc_group 0x%08x (transport %s) "
67 "is not available on transport %s\n",
72 return talloc_reference(conn
, assoc_group
);
75 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group
*assoc_group
)
79 dcesrv_assoc_group_common_destructor(assoc_group
);
81 ret
= idr_remove(assoc_group
->dce_ctx
->assoc_groups_idr
, assoc_group
->id
);
83 DEBUG(0,(__location__
": Failed to remove assoc_group 0x%08x\n",
86 SMB_ASSERT(assoc_group
->dce_ctx
->assoc_groups_num
> 0);
87 assoc_group
->dce_ctx
->assoc_groups_num
-= 1;
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
;
103 assoc_group
= talloc_zero(conn
, struct dcesrv_assoc_group
);
104 if (assoc_group
== NULL
) {
108 id
= idr_get_new_random(
109 dce_ctx
->assoc_groups_idr
, assoc_group
, 1, UINT16_MAX
);
111 talloc_free(assoc_group
);
112 DEBUG(0,(__location__
": Out of association groups!\n"));
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;
128 NTSTATUS
dcesrv_assoc_group_find_s4(
129 struct dcesrv_call_state
*call
,
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
);
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
;
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
;
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
)
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
;
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
,
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",
223 stream_terminate_connection(srv_conn
, nt_errstr(status
));
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
,
237 dcesrv_sock
->endpoint
,
238 srv_conn
->session_info
,
240 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
242 if (!NT_STATUS_IS_OK(status
)) {
243 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
245 stream_terminate_connection(srv_conn
, nt_errstr(status
));
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",
260 stream_terminate_connection(srv_conn
, nt_errstr(status
));
264 if (transport
== NCACN_NP
) {
265 dcesrv_conn
->stream
= talloc_move(dcesrv_conn
,
268 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
269 socket_get_fd(srv_conn
->socket
),
270 &dcesrv_conn
->stream
);
272 status
= map_nt_error_from_unix_common(errno
);
273 DEBUG(0, ("dcesrv_sock_accept: "
274 "failed to setup tstream: %s\n",
276 stream_terminate_connection(srv_conn
, nt_errstr(status
));
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
) {
292 sock_fd
= socket_get_fd(srv_conn
->socket
);
294 stream_terminate_connection(
295 srv_conn
, "socket_get_fd failed\n");
299 ret
= getpeereid(sock_fd
, &uid
, &gid
);
301 status
= map_nt_error_from_unix_common(errno
);
302 DEBUG(0, ("dcesrv_sock_accept: "
303 "getpeereid() failed for NCALRPC: %s\n",
305 stream_terminate_connection(srv_conn
, nt_errstr(status
));
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
,
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",
319 stream_terminate_connection(srv_conn
, nt_errstr(status
));
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",
332 stream_terminate_connection(srv_conn
, nt_errstr(status
));
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
= {
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
;
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
)));
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
;
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
,
421 if (!NT_STATUS_IS_OK(status
)) {
422 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
428 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx
),
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
)));
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
;
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
,
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
)));
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
,
495 void *process_context
)
497 struct dcesrv_socket_context
*dcesrv_sock
;
500 const char *endpoint
;
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 ",
524 for (iface
= e
->interface_list
; iface
; iface
= iface
->next
) {
525 DEBUGADD(0, ("%s ", iface
->iface
->name
));
527 DEBUGADD(0, ("failed - %s\n",
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
)));
541 struct dcesrv_if_list
*iface
;
542 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
544 for (iface
= e
->interface_list
; iface
; iface
= iface
->next
) {
545 DEBUGADD(4, ("%s ", iface
->iface
->name
));
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
)
564 /* Add TCP/IP sockets */
565 if (lpcfg_interfaces(lp_ctx
) && lpcfg_bind_interfaces_only(lp_ctx
)) {
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
,
578 NT_STATUS_NOT_OK_RETURN(status
);
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
,
590 if (NT_STATUS_IS_OK(status
)) {
595 if (num_binds
== 0) {
596 return NT_STATUS_INVALID_PARAMETER_MIX
;
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
);
614 case NCACN_UNIX_STREAM
:
615 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
,
616 model_ops
, process_context
);
619 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
,
620 model_ops
, process_context
);
623 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
,
624 model_ops
, process_context
);
627 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
,
628 model_ops
, process_context
);
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
,
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
,
679 transport_protection
,
681 NULL
/* client_audit_info */,
682 NULL
/* server_audit_info */);
684 auth
->auth_audited
= true;
687 NTSTATUS
dcesrv_gensec_prepare(
689 struct dcesrv_call_state
*call
,
690 struct gensec_security
**out
,
693 struct cli_credentials
*server_creds
= NULL
;
694 struct imessaging_context
*imsg_ctx
=
695 dcesrv_imessaging_context(call
->conn
);
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
,
709 DBG_WARNING("Failed to set kerberos state\n");
710 return NT_STATUS_INTERNAL_ERROR
;
713 return samba_server_gensec_start(mem_ctx
,
716 call
->conn
->dce_ctx
->lp_ctx
,
722 void dcesrv_transport_terminate_connection_s4(struct dcesrv_connection
*dce_conn
,
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
);