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",
72 return talloc_reference(conn
, assoc_group
);
75 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group
*assoc_group
)
78 ret
= idr_remove(assoc_group
->dce_ctx
->assoc_groups_idr
, assoc_group
->id
);
80 DEBUG(0,(__location__
": Failed to remove assoc_group 0x%08x\n",
87 allocate a new association group
89 static struct dcesrv_assoc_group
*dcesrv_assoc_group_new(struct dcesrv_connection
*conn
)
91 struct dcesrv_context
*dce_ctx
= conn
->dce_ctx
;
92 const struct dcesrv_endpoint
*endpoint
= conn
->endpoint
;
93 enum dcerpc_transport_t transport
=
94 dcerpc_binding_get_transport(endpoint
->ep_description
);
95 struct dcesrv_assoc_group
*assoc_group
;
98 assoc_group
= talloc_zero(conn
, struct dcesrv_assoc_group
);
99 if (assoc_group
== NULL
) {
103 id
= idr_get_new_random(
104 dce_ctx
->assoc_groups_idr
, assoc_group
, 1, UINT16_MAX
);
106 talloc_free(assoc_group
);
107 DEBUG(0,(__location__
": Out of association groups!\n"));
111 assoc_group
->transport
= transport
;
112 assoc_group
->id
= id
;
113 assoc_group
->dce_ctx
= dce_ctx
;
115 talloc_set_destructor(assoc_group
, dcesrv_assoc_group_destructor
);
120 NTSTATUS
dcesrv_assoc_group_find_s4(
121 struct dcesrv_call_state
*call
,
125 if provided, check the assoc_group is valid
127 if (call
->pkt
.u
.bind
.assoc_group_id
!= 0) {
128 call
->conn
->assoc_group
=
129 dcesrv_assoc_group_reference(call
->conn
,
130 call
->pkt
.u
.bind
.assoc_group_id
);
132 call
->conn
->assoc_group
= dcesrv_assoc_group_new(call
->conn
);
136 * The NETLOGON server does not use handles and so
137 * there is no need to support association groups, but
138 * we need to give back a number regardless.
140 * We have to do this when it is not run as a single process,
141 * because then it can't see the other valid association
142 * groups. We handle this genericly for all endpoints not
143 * running in single process mode.
145 * We know which endpoint we are on even before checking the
146 * iface UUID, so for simplicity we enforce the same policy
147 * for all interfaces on the endpoint.
149 * This means that where NETLOGON
150 * shares an endpoint (such as ncalrpc or if 'lsa over
151 * netlogon' is set) we will still check association groups.
155 if (call
->conn
->assoc_group
== NULL
&&
156 !call
->conn
->endpoint
->use_single_process
) {
157 call
->conn
->assoc_group
158 = dcesrv_assoc_group_new(call
->conn
);
161 if (call
->conn
->assoc_group
== NULL
) {
162 /* TODO Return correct status */
163 return NT_STATUS_UNSUCCESSFUL
;
169 void dcerpc_server_init(struct loadparm_context
*lp_ctx
)
171 static bool initialized
;
172 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
173 STATIC_dcerpc_server_MODULES_PROTO
;
174 init_module_fn static_init
[] = { STATIC_dcerpc_server_MODULES
};
175 init_module_fn
*shared_init
;
182 shared_init
= load_samba_modules(NULL
, "dcerpc_server");
184 run_init_functions(NULL
, static_init
);
185 run_init_functions(NULL
, shared_init
);
187 talloc_free(shared_init
);
190 struct dcesrv_socket_context
{
191 const struct dcesrv_endpoint
*endpoint
;
192 struct dcesrv_context
*dcesrv_ctx
;
195 static void dcesrv_sock_accept(struct stream_connection
*srv_conn
)
198 struct dcesrv_socket_context
*dcesrv_sock
=
199 talloc_get_type(srv_conn
->private_data
, struct dcesrv_socket_context
);
200 enum dcerpc_transport_t transport
=
201 dcerpc_binding_get_transport(dcesrv_sock
->endpoint
->ep_description
);
202 struct dcesrv_connection
*dcesrv_conn
= NULL
;
204 struct loadparm_context
*lp_ctx
= dcesrv_sock
->dcesrv_ctx
->lp_ctx
;
206 dcesrv_cleanup_broken_connections(dcesrv_sock
->dcesrv_ctx
);
208 if (!srv_conn
->session_info
) {
209 status
= auth_anonymous_session_info(srv_conn
,
211 &srv_conn
->session_info
);
212 if (!NT_STATUS_IS_OK(status
)) {
213 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
215 stream_terminate_connection(srv_conn
, nt_errstr(status
));
221 * This fills in dcesrv_conn->endpoint with the endpoint
222 * associated with the socket. From this point on we know
223 * which (group of) services we are handling, but not the
224 * specific interface.
227 status
= dcesrv_endpoint_connect(dcesrv_sock
->dcesrv_ctx
,
229 dcesrv_sock
->endpoint
,
230 srv_conn
->session_info
,
232 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
234 if (!NT_STATUS_IS_OK(status
)) {
235 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
237 stream_terminate_connection(srv_conn
, nt_errstr(status
));
241 dcesrv_conn
->transport
.private_data
= srv_conn
;
242 dcesrv_conn
->transport
.report_output_data
= dcesrv_sock_report_output_data
;
243 dcesrv_conn
->transport
.terminate_connection
= dcesrv_transport_terminate_connection_s4
;
245 TALLOC_FREE(srv_conn
->event
.fde
);
247 dcesrv_conn
->send_queue
= tevent_queue_create(dcesrv_conn
, "dcesrv send queue");
248 if (!dcesrv_conn
->send_queue
) {
249 status
= NT_STATUS_NO_MEMORY
;
250 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
252 stream_terminate_connection(srv_conn
, nt_errstr(status
));
256 if (transport
== NCACN_NP
) {
257 dcesrv_conn
->stream
= talloc_move(dcesrv_conn
,
260 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
261 socket_get_fd(srv_conn
->socket
),
262 &dcesrv_conn
->stream
);
264 status
= map_nt_error_from_unix_common(errno
);
265 DEBUG(0, ("dcesrv_sock_accept: "
266 "failed to setup tstream: %s\n",
268 stream_terminate_connection(srv_conn
, nt_errstr(status
));
271 socket_set_flags(srv_conn
->socket
, SOCKET_FLAG_NOCLOSE
);
274 dcesrv_conn
->local_address
= srv_conn
->local_address
;
275 dcesrv_conn
->remote_address
= srv_conn
->remote_address
;
277 if (transport
== NCALRPC
) {
282 sock_fd
= socket_get_fd(srv_conn
->socket
);
284 stream_terminate_connection(
285 srv_conn
, "socket_get_fd failed\n");
289 ret
= getpeereid(sock_fd
, &uid
, &gid
);
291 status
= map_nt_error_from_unix_common(errno
);
292 DEBUG(0, ("dcesrv_sock_accept: "
293 "getpeereid() failed for NCALRPC: %s\n",
295 stream_terminate_connection(srv_conn
, nt_errstr(status
));
298 if (uid
== dcesrv_conn
->dce_ctx
->initial_euid
) {
299 struct tsocket_address
*r
= NULL
;
301 ret
= tsocket_address_unix_from_path(dcesrv_conn
,
302 AS_SYSTEM_MAGIC_PATH_TOKEN
,
305 status
= map_nt_error_from_unix_common(errno
);
306 DEBUG(0, ("dcesrv_sock_accept: "
307 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
309 stream_terminate_connection(srv_conn
, nt_errstr(status
));
312 dcesrv_conn
->remote_address
= r
;
316 srv_conn
->private_data
= dcesrv_conn
;
318 status
= dcesrv_connection_loop_start(dcesrv_conn
);
319 if (!NT_STATUS_IS_OK(status
)) {
320 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
322 stream_terminate_connection(srv_conn
, nt_errstr(status
));
329 static void dcesrv_sock_recv(struct stream_connection
*conn
, uint16_t flags
)
331 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
332 struct dcesrv_connection
);
333 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_recv triggered");
336 static void dcesrv_sock_send(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_send triggered");
344 static const struct stream_server_ops dcesrv_stream_ops
= {
346 .accept_connection
= dcesrv_sock_accept
,
347 .recv_handler
= dcesrv_sock_recv
,
348 .send_handler
= dcesrv_sock_send
,
351 static NTSTATUS
dcesrv_add_ep_unix(struct dcesrv_context
*dce_ctx
,
352 struct loadparm_context
*lp_ctx
,
353 struct dcesrv_endpoint
*e
,
354 struct tevent_context
*event_ctx
,
355 const struct model_ops
*model_ops
,
356 void *process_context
)
358 struct dcesrv_socket_context
*dcesrv_sock
;
361 const char *endpoint
;
363 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
364 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
366 /* remember the endpoint of this socket */
367 dcesrv_sock
->endpoint
= e
;
368 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
370 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
372 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, lp_ctx
,
373 model_ops
, &dcesrv_stream_ops
,
374 "unix", endpoint
, &port
,
375 lpcfg_socket_options(lp_ctx
),
376 dcesrv_sock
, process_context
);
377 if (!NT_STATUS_IS_OK(status
)) {
378 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
379 endpoint
, nt_errstr(status
)));
385 static NTSTATUS
dcesrv_add_ep_ncalrpc(struct dcesrv_context
*dce_ctx
,
386 struct loadparm_context
*lp_ctx
,
387 struct dcesrv_endpoint
*e
,
388 struct tevent_context
*event_ctx
,
389 const struct model_ops
*model_ops
,
390 void *process_context
)
392 struct dcesrv_socket_context
*dcesrv_sock
;
396 const char *endpoint
;
398 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
400 if (endpoint
== NULL
) {
402 * No identifier specified: use DEFAULT.
404 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
405 * no endpoint and let the epmapper worry about it.
407 endpoint
= "DEFAULT";
408 status
= dcerpc_binding_set_string_option(e
->ep_description
,
411 if (!NT_STATUS_IS_OK(status
)) {
412 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
418 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx
),
421 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
422 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
424 /* remember the endpoint of this socket */
425 dcesrv_sock
->endpoint
= e
;
426 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
428 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, lp_ctx
,
429 model_ops
, &dcesrv_stream_ops
,
430 "unix", full_path
, &port
,
431 lpcfg_socket_options(lp_ctx
),
432 dcesrv_sock
, process_context
);
433 if (!NT_STATUS_IS_OK(status
)) {
434 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
435 endpoint
, full_path
, nt_errstr(status
)));
440 static NTSTATUS
dcesrv_add_ep_np(struct dcesrv_context
*dce_ctx
,
441 struct loadparm_context
*lp_ctx
,
442 struct dcesrv_endpoint
*e
,
443 struct tevent_context
*event_ctx
,
444 const struct model_ops
*model_ops
,
445 void *process_context
)
447 struct dcesrv_socket_context
*dcesrv_sock
;
449 const char *endpoint
;
451 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
452 if (endpoint
== NULL
) {
453 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
454 return NT_STATUS_INVALID_PARAMETER
;
457 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
458 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
460 /* remember the endpoint of this socket */
461 dcesrv_sock
->endpoint
= e
;
462 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
464 status
= tstream_setup_named_pipe(dce_ctx
, event_ctx
, lp_ctx
,
465 model_ops
, &dcesrv_stream_ops
,
467 dcesrv_sock
, process_context
);
468 if (!NT_STATUS_IS_OK(status
)) {
469 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
470 endpoint
, nt_errstr(status
)));
478 add a socket address to the list of events, one event per dcerpc endpoint
480 static NTSTATUS
add_socket_rpc_tcp_iface(struct dcesrv_context
*dce_ctx
,
481 struct dcesrv_endpoint
*e
,
482 struct tevent_context
*event_ctx
,
483 const struct model_ops
*model_ops
,
485 void *process_context
)
487 struct dcesrv_socket_context
*dcesrv_sock
;
490 const char *endpoint
;
493 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
494 if (endpoint
!= NULL
) {
495 port
= atoi(endpoint
);
498 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
499 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
501 /* remember the endpoint of this socket */
502 dcesrv_sock
->endpoint
= e
;
503 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
505 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, dce_ctx
->lp_ctx
,
506 model_ops
, &dcesrv_stream_ops
,
507 "ip", address
, &port
,
508 lpcfg_socket_options(dce_ctx
->lp_ctx
),
509 dcesrv_sock
, process_context
);
510 if (!NT_STATUS_IS_OK(status
)) {
511 struct dcesrv_if_list
*iface
;
512 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
514 for (iface
= e
->interface_list
; iface
; iface
= iface
->next
) {
515 DEBUGADD(0, ("%s ", iface
->iface
->name
));
517 DEBUGADD(0, ("failed - %s\n",
522 snprintf(port_str
, sizeof(port_str
), "%u", port
);
524 status
= dcerpc_binding_set_string_option(e
->ep_description
,
525 "endpoint", port_str
);
526 if (!NT_STATUS_IS_OK(status
)) {
527 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
528 port_str
, nt_errstr(status
)));
531 struct dcesrv_if_list
*iface
;
532 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
534 for (iface
= e
->interface_list
; iface
; iface
= iface
->next
) {
535 DEBUGADD(4, ("%s ", iface
->iface
->name
));
543 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
545 static NTSTATUS
dcesrv_add_ep_tcp(struct dcesrv_context
*dce_ctx
,
546 struct loadparm_context
*lp_ctx
,
547 struct dcesrv_endpoint
*e
,
548 struct tevent_context
*event_ctx
,
549 const struct model_ops
*model_ops
,
550 void *process_context
)
554 /* Add TCP/IP sockets */
555 if (lpcfg_interfaces(lp_ctx
) && lpcfg_bind_interfaces_only(lp_ctx
)) {
558 struct interface
*ifaces
;
560 load_interface_list(dce_ctx
, lp_ctx
, &ifaces
);
562 num_interfaces
= iface_list_count(ifaces
);
563 for(i
= 0; i
< num_interfaces
; i
++) {
564 const char *address
= iface_list_n_ip(ifaces
, i
);
565 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
,
568 NT_STATUS_NOT_OK_RETURN(status
);
573 size_t num_binds
= 0;
574 wcard
= iface_list_wildcard(dce_ctx
);
575 NT_STATUS_HAVE_NO_MEMORY(wcard
);
576 for (i
=0; wcard
[i
]; i
++) {
577 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
,
580 if (NT_STATUS_IS_OK(status
)) {
585 if (num_binds
== 0) {
586 return NT_STATUS_INVALID_PARAMETER_MIX
;
593 NTSTATUS
dcesrv_add_ep(struct dcesrv_context
*dce_ctx
,
594 struct loadparm_context
*lp_ctx
,
595 struct dcesrv_endpoint
*e
,
596 struct tevent_context
*event_ctx
,
597 const struct model_ops
*model_ops
,
598 void *process_context
)
600 enum dcerpc_transport_t transport
=
601 dcerpc_binding_get_transport(e
->ep_description
);
604 case NCACN_UNIX_STREAM
:
605 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
,
606 model_ops
, process_context
);
609 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
,
610 model_ops
, process_context
);
613 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
,
614 model_ops
, process_context
);
617 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
,
618 model_ops
, process_context
);
621 return NT_STATUS_NOT_SUPPORTED
;
625 _PUBLIC_
struct imessaging_context
*dcesrv_imessaging_context(
626 struct dcesrv_connection
*conn
)
628 struct stream_connection
*srv_conn
=
629 talloc_get_type_abort(conn
->transport
.private_data
,
630 struct stream_connection
);
631 return srv_conn
->msg_ctx
;
634 _PUBLIC_
struct server_id
dcesrv_server_id(struct dcesrv_connection
*conn
)
636 struct stream_connection
*srv_conn
=
637 talloc_get_type_abort(conn
->transport
.private_data
,
638 struct stream_connection
);
639 return srv_conn
->server_id
;
642 void log_successful_dcesrv_authz_event(
643 struct dcesrv_call_state
*call
,
646 struct dcesrv_auth
*auth
= call
->auth_state
;
647 enum dcerpc_transport_t transport
=
648 dcerpc_binding_get_transport(call
->conn
->endpoint
->ep_description
);
649 struct imessaging_context
*imsg_ctx
=
650 dcesrv_imessaging_context(call
->conn
);
651 const char *auth_type
= derpc_transport_string_by_transport(transport
);
652 const char *transport_protection
= AUTHZ_TRANSPORT_PROTECTION_NONE
;
654 if (transport
== NCACN_NP
) {
655 transport_protection
= AUTHZ_TRANSPORT_PROTECTION_SMB
;
659 * Log the authorization to this RPC interface. This
660 * covered ncacn_np pass-through auth, and anonymous
661 * DCE/RPC (eg epmapper, netlogon etc)
663 log_successful_authz_event(imsg_ctx
,
664 call
->conn
->dce_ctx
->lp_ctx
,
665 call
->conn
->remote_address
,
666 call
->conn
->local_address
,
669 transport_protection
,
672 auth
->auth_audited
= true;
675 NTSTATUS
dcesrv_gensec_prepare(
677 struct dcesrv_call_state
*call
,
678 struct gensec_security
**out
,
681 struct cli_credentials
*server_creds
= NULL
;
682 struct imessaging_context
*imsg_ctx
=
683 dcesrv_imessaging_context(call
->conn
);
686 server_creds
= cli_credentials_init_server(call
->auth_state
,
687 call
->conn
->dce_ctx
->lp_ctx
);
688 if (server_creds
== NULL
) {
689 DEBUG(1, ("Failed to init server credentials\n"));
690 return NT_STATUS_NO_MEMORY
;
692 /* This is required for ncalrpc_as_system. */
693 ok
= cli_credentials_set_kerberos_state(server_creds
,
694 CRED_USE_KERBEROS_DESIRED
,
697 DBG_WARNING("Failed to set kerberos state\n");
698 return NT_STATUS_INTERNAL_ERROR
;
701 return samba_server_gensec_start(mem_ctx
,
704 call
->conn
->dce_ctx
->lp_ctx
,
710 void dcesrv_transport_terminate_connection_s4(struct dcesrv_connection
*dce_conn
,
713 struct stream_connection
*srv_conn
=
714 talloc_get_type_abort(dce_conn
->transport
.private_data
,
715 struct stream_connection
);
716 stream_terminate_connection(srv_conn
, reason
);