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"
38 take a reference to an existing association group
40 static struct dcesrv_assoc_group
*dcesrv_assoc_group_reference(struct dcesrv_connection
*conn
,
43 const struct dcesrv_endpoint
*endpoint
= conn
->endpoint
;
44 enum dcerpc_transport_t transport
=
45 dcerpc_binding_get_transport(endpoint
->ep_description
);
46 struct dcesrv_assoc_group
*assoc_group
;
49 /* find an association group given a assoc_group_id */
50 id_ptr
= idr_find(conn
->dce_ctx
->assoc_groups_idr
, id
);
52 DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id
);
55 assoc_group
= talloc_get_type_abort(id_ptr
, struct dcesrv_assoc_group
);
57 if (assoc_group
->transport
!= transport
) {
59 derpc_transport_string_by_transport(
60 assoc_group
->transport
);
62 derpc_transport_string_by_transport(
65 DBG_NOTICE("assoc_group 0x%08x (transport %s) "
66 "is not available on transport %s",
71 return talloc_reference(conn
, assoc_group
);
74 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group
*assoc_group
)
77 ret
= idr_remove(assoc_group
->dce_ctx
->assoc_groups_idr
, assoc_group
->id
);
79 DEBUG(0,(__location__
": Failed to remove assoc_group 0x%08x\n",
86 allocate a new association group
88 static struct dcesrv_assoc_group
*dcesrv_assoc_group_new(struct dcesrv_connection
*conn
)
90 struct dcesrv_context
*dce_ctx
= conn
->dce_ctx
;
91 const struct dcesrv_endpoint
*endpoint
= conn
->endpoint
;
92 enum dcerpc_transport_t transport
=
93 dcerpc_binding_get_transport(endpoint
->ep_description
);
94 struct dcesrv_assoc_group
*assoc_group
;
97 assoc_group
= talloc_zero(conn
, struct dcesrv_assoc_group
);
98 if (assoc_group
== NULL
) {
102 id
= idr_get_new_random(dce_ctx
->assoc_groups_idr
, assoc_group
, UINT16_MAX
);
104 talloc_free(assoc_group
);
105 DEBUG(0,(__location__
": Out of association groups!\n"));
109 assoc_group
->transport
= transport
;
110 assoc_group
->id
= id
;
111 assoc_group
->dce_ctx
= dce_ctx
;
113 talloc_set_destructor(assoc_group
, dcesrv_assoc_group_destructor
);
118 NTSTATUS
dcesrv_assoc_group_find(
119 struct dcesrv_call_state
*call
,
123 if provided, check the assoc_group is valid
125 if (call
->pkt
.u
.bind
.assoc_group_id
!= 0) {
126 call
->conn
->assoc_group
=
127 dcesrv_assoc_group_reference(call
->conn
,
128 call
->pkt
.u
.bind
.assoc_group_id
);
130 call
->conn
->assoc_group
= dcesrv_assoc_group_new(call
->conn
);
134 * The NETLOGON server does not use handles and so
135 * there is no need to support association groups, but
136 * we need to give back a number regardless.
138 * We have to do this when it is not run as a single process,
139 * because then it can't see the other valid association
140 * groups. We handle this genericly for all endpoints not
141 * running in single process mode.
143 * We know which endpoint we are on even before checking the
144 * iface UUID, so for simplicity we enforce the same policy
145 * for all interfaces on the endpoint.
147 * This means that where NETLOGON
148 * shares an endpoint (such as ncalrpc or if 'lsa over
149 * netlogon' is set) we will still check association groups.
153 if (call
->conn
->assoc_group
== NULL
&&
154 !call
->conn
->endpoint
->use_single_process
) {
155 call
->conn
->assoc_group
156 = dcesrv_assoc_group_new(call
->conn
);
159 if (call
->conn
->assoc_group
== NULL
) {
160 /* TODO Return correct status */
161 return NT_STATUS_UNSUCCESSFUL
;
167 void dcerpc_server_init(struct loadparm_context
*lp_ctx
)
169 static bool initialized
;
170 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
171 STATIC_dcerpc_server_MODULES_PROTO
;
172 init_module_fn static_init
[] = { STATIC_dcerpc_server_MODULES
};
173 init_module_fn
*shared_init
;
180 shared_init
= load_samba_modules(NULL
, "dcerpc_server");
182 run_init_functions(NULL
, static_init
);
183 run_init_functions(NULL
, shared_init
);
185 talloc_free(shared_init
);
188 struct dcesrv_socket_context
{
189 const struct dcesrv_endpoint
*endpoint
;
190 struct dcesrv_context
*dcesrv_ctx
;
193 static void dcesrv_sock_accept(struct stream_connection
*srv_conn
)
196 struct dcesrv_socket_context
*dcesrv_sock
=
197 talloc_get_type(srv_conn
->private_data
, struct dcesrv_socket_context
);
198 enum dcerpc_transport_t transport
=
199 dcerpc_binding_get_transport(dcesrv_sock
->endpoint
->ep_description
);
200 struct dcesrv_connection
*dcesrv_conn
= NULL
;
202 struct loadparm_context
*lp_ctx
= dcesrv_sock
->dcesrv_ctx
->lp_ctx
;
204 dcesrv_cleanup_broken_connections(dcesrv_sock
->dcesrv_ctx
);
206 if (!srv_conn
->session_info
) {
207 status
= auth_anonymous_session_info(srv_conn
,
209 &srv_conn
->session_info
);
210 if (!NT_STATUS_IS_OK(status
)) {
211 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
213 stream_terminate_connection(srv_conn
, nt_errstr(status
));
219 * This fills in dcesrv_conn->endpoint with the endpoint
220 * associated with the socket. From this point on we know
221 * which (group of) services we are handling, but not the
222 * specific interface.
225 status
= dcesrv_endpoint_connect(dcesrv_sock
->dcesrv_ctx
,
227 dcesrv_sock
->endpoint
,
228 srv_conn
->session_info
,
230 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
232 if (!NT_STATUS_IS_OK(status
)) {
233 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
235 stream_terminate_connection(srv_conn
, nt_errstr(status
));
239 dcesrv_conn
->transport
.private_data
= srv_conn
;
240 dcesrv_conn
->transport
.report_output_data
= dcesrv_sock_report_output_data
;
241 dcesrv_conn
->transport
.terminate_connection
= dcesrv_transport_terminate_connection
;
243 TALLOC_FREE(srv_conn
->event
.fde
);
245 dcesrv_conn
->send_queue
= tevent_queue_create(dcesrv_conn
, "dcesrv send queue");
246 if (!dcesrv_conn
->send_queue
) {
247 status
= NT_STATUS_NO_MEMORY
;
248 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
250 stream_terminate_connection(srv_conn
, nt_errstr(status
));
254 if (transport
== NCACN_NP
) {
255 dcesrv_conn
->stream
= talloc_move(dcesrv_conn
,
258 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
259 socket_get_fd(srv_conn
->socket
),
260 &dcesrv_conn
->stream
);
262 status
= map_nt_error_from_unix_common(errno
);
263 DEBUG(0, ("dcesrv_sock_accept: "
264 "failed to setup tstream: %s\n",
266 stream_terminate_connection(srv_conn
, nt_errstr(status
));
269 socket_set_flags(srv_conn
->socket
, SOCKET_FLAG_NOCLOSE
);
272 dcesrv_conn
->local_address
= srv_conn
->local_address
;
273 dcesrv_conn
->remote_address
= srv_conn
->remote_address
;
275 if (transport
== NCALRPC
) {
280 sock_fd
= socket_get_fd(srv_conn
->socket
);
282 stream_terminate_connection(
283 srv_conn
, "socket_get_fd failed\n");
287 ret
= getpeereid(sock_fd
, &uid
, &gid
);
289 status
= map_nt_error_from_unix_common(errno
);
290 DEBUG(0, ("dcesrv_sock_accept: "
291 "getpeereid() failed for NCALRPC: %s\n",
293 stream_terminate_connection(srv_conn
, nt_errstr(status
));
296 if (uid
== dcesrv_conn
->dce_ctx
->initial_euid
) {
297 struct tsocket_address
*r
= NULL
;
299 ret
= tsocket_address_unix_from_path(dcesrv_conn
,
300 AS_SYSTEM_MAGIC_PATH_TOKEN
,
303 status
= map_nt_error_from_unix_common(errno
);
304 DEBUG(0, ("dcesrv_sock_accept: "
305 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
307 stream_terminate_connection(srv_conn
, nt_errstr(status
));
310 dcesrv_conn
->remote_address
= r
;
314 srv_conn
->private_data
= dcesrv_conn
;
316 status
= dcesrv_connection_loop_start(dcesrv_conn
);
317 if (!NT_STATUS_IS_OK(status
)) {
318 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
320 stream_terminate_connection(srv_conn
, nt_errstr(status
));
327 static void dcesrv_sock_recv(struct stream_connection
*conn
, uint16_t flags
)
329 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
330 struct dcesrv_connection
);
331 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_recv triggered");
334 static void dcesrv_sock_send(struct stream_connection
*conn
, uint16_t flags
)
336 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
337 struct dcesrv_connection
);
338 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_send triggered");
342 static const struct stream_server_ops dcesrv_stream_ops
= {
344 .accept_connection
= dcesrv_sock_accept
,
345 .recv_handler
= dcesrv_sock_recv
,
346 .send_handler
= dcesrv_sock_send
,
349 static NTSTATUS
dcesrv_add_ep_unix(struct dcesrv_context
*dce_ctx
,
350 struct loadparm_context
*lp_ctx
,
351 struct dcesrv_endpoint
*e
,
352 struct tevent_context
*event_ctx
,
353 const struct model_ops
*model_ops
,
354 void *process_context
)
356 struct dcesrv_socket_context
*dcesrv_sock
;
359 const char *endpoint
;
361 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
362 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
364 /* remember the endpoint of this socket */
365 dcesrv_sock
->endpoint
= e
;
366 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
368 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
370 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, lp_ctx
,
371 model_ops
, &dcesrv_stream_ops
,
372 "unix", endpoint
, &port
,
373 lpcfg_socket_options(lp_ctx
),
374 dcesrv_sock
, process_context
);
375 if (!NT_STATUS_IS_OK(status
)) {
376 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
377 endpoint
, nt_errstr(status
)));
383 static NTSTATUS
dcesrv_add_ep_ncalrpc(struct dcesrv_context
*dce_ctx
,
384 struct loadparm_context
*lp_ctx
,
385 struct dcesrv_endpoint
*e
,
386 struct tevent_context
*event_ctx
,
387 const struct model_ops
*model_ops
,
388 void *process_context
)
390 struct dcesrv_socket_context
*dcesrv_sock
;
394 const char *endpoint
;
396 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
398 if (endpoint
== NULL
) {
400 * No identifier specified: use DEFAULT.
402 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
403 * no endpoint and let the epmapper worry about it.
405 endpoint
= "DEFAULT";
406 status
= dcerpc_binding_set_string_option(e
->ep_description
,
409 if (!NT_STATUS_IS_OK(status
)) {
410 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
416 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx
),
419 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
420 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
422 /* remember the endpoint of this socket */
423 dcesrv_sock
->endpoint
= e
;
424 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
426 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, lp_ctx
,
427 model_ops
, &dcesrv_stream_ops
,
428 "unix", full_path
, &port
,
429 lpcfg_socket_options(lp_ctx
),
430 dcesrv_sock
, process_context
);
431 if (!NT_STATUS_IS_OK(status
)) {
432 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
433 endpoint
, full_path
, nt_errstr(status
)));
438 static NTSTATUS
dcesrv_add_ep_np(struct dcesrv_context
*dce_ctx
,
439 struct loadparm_context
*lp_ctx
,
440 struct dcesrv_endpoint
*e
,
441 struct tevent_context
*event_ctx
,
442 const struct model_ops
*model_ops
,
443 void *process_context
)
445 struct dcesrv_socket_context
*dcesrv_sock
;
447 const char *endpoint
;
449 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
450 if (endpoint
== NULL
) {
451 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
452 return NT_STATUS_INVALID_PARAMETER
;
455 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
456 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
458 /* remember the endpoint of this socket */
459 dcesrv_sock
->endpoint
= e
;
460 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
462 status
= tstream_setup_named_pipe(dce_ctx
, event_ctx
, lp_ctx
,
463 model_ops
, &dcesrv_stream_ops
,
465 dcesrv_sock
, process_context
);
466 if (!NT_STATUS_IS_OK(status
)) {
467 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
468 endpoint
, nt_errstr(status
)));
476 add a socket address to the list of events, one event per dcerpc endpoint
478 static NTSTATUS
add_socket_rpc_tcp_iface(struct dcesrv_context
*dce_ctx
,
479 struct dcesrv_endpoint
*e
,
480 struct tevent_context
*event_ctx
,
481 const struct model_ops
*model_ops
,
483 void *process_context
)
485 struct dcesrv_socket_context
*dcesrv_sock
;
488 const char *endpoint
;
491 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
492 if (endpoint
!= NULL
) {
493 port
= atoi(endpoint
);
496 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
497 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
499 /* remember the endpoint of this socket */
500 dcesrv_sock
->endpoint
= e
;
501 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
503 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, dce_ctx
->lp_ctx
,
504 model_ops
, &dcesrv_stream_ops
,
505 "ip", address
, &port
,
506 lpcfg_socket_options(dce_ctx
->lp_ctx
),
507 dcesrv_sock
, process_context
);
508 if (!NT_STATUS_IS_OK(status
)) {
509 struct dcesrv_if_list
*iface
;
510 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
512 for (iface
= e
->interface_list
; iface
; iface
= iface
->next
) {
513 DEBUGADD(0, ("%s ", iface
->iface
->name
));
515 DEBUGADD(0, ("failed - %s\n",
520 snprintf(port_str
, sizeof(port_str
), "%u", port
);
522 status
= dcerpc_binding_set_string_option(e
->ep_description
,
523 "endpoint", port_str
);
524 if (!NT_STATUS_IS_OK(status
)) {
525 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
526 port_str
, nt_errstr(status
)));
529 struct dcesrv_if_list
*iface
;
530 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
532 for (iface
= e
->interface_list
; iface
; iface
= iface
->next
) {
533 DEBUGADD(4, ("%s ", iface
->iface
->name
));
541 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
543 static NTSTATUS
dcesrv_add_ep_tcp(struct dcesrv_context
*dce_ctx
,
544 struct loadparm_context
*lp_ctx
,
545 struct dcesrv_endpoint
*e
,
546 struct tevent_context
*event_ctx
,
547 const struct model_ops
*model_ops
,
548 void *process_context
)
552 /* Add TCP/IP sockets */
553 if (lpcfg_interfaces(lp_ctx
) && lpcfg_bind_interfaces_only(lp_ctx
)) {
556 struct interface
*ifaces
;
558 load_interface_list(dce_ctx
, lp_ctx
, &ifaces
);
560 num_interfaces
= iface_list_count(ifaces
);
561 for(i
= 0; i
< num_interfaces
; i
++) {
562 const char *address
= iface_list_n_ip(ifaces
, i
);
563 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
,
566 NT_STATUS_NOT_OK_RETURN(status
);
571 size_t num_binds
= 0;
572 wcard
= iface_list_wildcard(dce_ctx
);
573 NT_STATUS_HAVE_NO_MEMORY(wcard
);
574 for (i
=0; wcard
[i
]; i
++) {
575 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
,
578 if (NT_STATUS_IS_OK(status
)) {
583 if (num_binds
== 0) {
584 return NT_STATUS_INVALID_PARAMETER_MIX
;
591 NTSTATUS
dcesrv_add_ep(struct dcesrv_context
*dce_ctx
,
592 struct loadparm_context
*lp_ctx
,
593 struct dcesrv_endpoint
*e
,
594 struct tevent_context
*event_ctx
,
595 const struct model_ops
*model_ops
,
596 void *process_context
)
598 enum dcerpc_transport_t transport
=
599 dcerpc_binding_get_transport(e
->ep_description
);
602 case NCACN_UNIX_STREAM
:
603 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
,
604 model_ops
, process_context
);
607 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
,
608 model_ops
, process_context
);
611 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
,
612 model_ops
, process_context
);
615 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
,
616 model_ops
, process_context
);
619 return NT_STATUS_NOT_SUPPORTED
;
623 _PUBLIC_
struct imessaging_context
*dcesrv_imessaging_context(
624 struct dcesrv_connection
*conn
)
626 struct stream_connection
*srv_conn
=
627 talloc_get_type_abort(conn
->transport
.private_data
,
628 struct stream_connection
);
629 return srv_conn
->msg_ctx
;
632 _PUBLIC_
struct server_id
dcesrv_server_id(struct dcesrv_connection
*conn
)
634 struct stream_connection
*srv_conn
=
635 talloc_get_type_abort(conn
->transport
.private_data
,
636 struct stream_connection
);
637 return srv_conn
->server_id
;
640 void log_successful_dcesrv_authz_event(
641 struct dcesrv_call_state
*call
,
644 struct dcesrv_auth
*auth
= call
->auth_state
;
645 enum dcerpc_transport_t transport
=
646 dcerpc_binding_get_transport(call
->conn
->endpoint
->ep_description
);
647 struct imessaging_context
*imsg_ctx
=
648 dcesrv_imessaging_context(call
->conn
);
649 const char *auth_type
= derpc_transport_string_by_transport(transport
);
650 const char *transport_protection
= AUTHZ_TRANSPORT_PROTECTION_NONE
;
652 if (transport
== NCACN_NP
) {
653 transport_protection
= AUTHZ_TRANSPORT_PROTECTION_SMB
;
657 * Log the authorization to this RPC interface. This
658 * covered ncacn_np pass-through auth, and anonymous
659 * DCE/RPC (eg epmapper, netlogon etc)
661 log_successful_authz_event(imsg_ctx
,
662 call
->conn
->dce_ctx
->lp_ctx
,
663 call
->conn
->remote_address
,
664 call
->conn
->local_address
,
667 transport_protection
,
670 auth
->auth_audited
= true;
673 NTSTATUS
dcesrv_gensec_prepare(
675 struct dcesrv_call_state
*call
,
676 struct gensec_security
**out
,
679 struct cli_credentials
*server_creds
= NULL
;
680 struct imessaging_context
*imsg_ctx
=
681 dcesrv_imessaging_context(call
->conn
);
684 server_creds
= cli_credentials_init_server(call
->auth_state
,
685 call
->conn
->dce_ctx
->lp_ctx
);
686 if (server_creds
== NULL
) {
687 DEBUG(1, ("Failed to init server credentials\n"));
688 return NT_STATUS_NO_MEMORY
;
690 /* This is required for ncalrpc_as_system. */
691 ok
= cli_credentials_set_kerberos_state(server_creds
,
692 CRED_USE_KERBEROS_DESIRED
,
695 DBG_WARNING("Failed to set kerberos state\n");
696 return NT_STATUS_INTERNAL_ERROR
;
699 return samba_server_gensec_start(mem_ctx
,
702 call
->conn
->dce_ctx
->lp_ctx
,
708 void dcesrv_transport_terminate_connection(struct dcesrv_connection
*dce_conn
,
711 struct stream_connection
*srv_conn
=
712 talloc_get_type_abort(dce_conn
->transport
.private_data
,
713 struct stream_connection
);
714 stream_terminate_connection(srv_conn
, reason
);