2 Unix SMB/CIFS implementation.
4 smbd-specific dcerpc server code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
8 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2004,2007
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "librpc/gen_ndr/ndr_dcerpc.h"
26 #include "auth/auth.h"
27 #include "../lib/util/dlinklist.h"
28 #include "rpc_server/dcerpc_server.h"
29 #include "rpc_server/dcerpc_server_proto.h"
30 #include "system/filesys.h"
31 #include "lib/messaging/irpc.h"
32 #include "system/network.h"
33 #include "lib/socket/netif.h"
34 #include "param/param.h"
35 #include "../lib/tsocket/tsocket.h"
36 #include "librpc/rpc/dcerpc_proto.h"
37 #include "../lib/util/tevent_ntstatus.h"
38 #include "libcli/raw/smb.h"
39 #include "../libcli/named_pipe_auth/npa_tstream.h"
40 #include "smbd/process_model.h"
42 struct dcesrv_socket_context
{
43 const struct dcesrv_endpoint
*endpoint
;
44 struct dcesrv_context
*dcesrv_ctx
;
47 static void dcesrv_terminate_connection(struct dcesrv_connection
*dce_conn
, const char *reason
)
49 struct stream_connection
*srv_conn
;
50 srv_conn
= talloc_get_type(dce_conn
->transport
.private_data
,
51 struct stream_connection
);
53 stream_terminate_connection(srv_conn
, reason
);
56 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
);
58 struct dcesrv_sock_reply_state
{
59 struct dcesrv_connection
*dce_conn
;
60 struct dcesrv_call_state
*call
;
64 static void dcesrv_sock_report_output_data(struct dcesrv_connection
*dce_conn
)
66 struct dcesrv_call_state
*call
;
68 call
= dce_conn
->call_list
;
69 if (!call
|| !call
->replies
) {
73 while (call
->replies
) {
74 struct data_blob_list_item
*rep
= call
->replies
;
75 struct dcesrv_sock_reply_state
*substate
;
76 struct tevent_req
*subreq
;
78 substate
= talloc(call
, struct dcesrv_sock_reply_state
);
80 dcesrv_terminate_connection(dce_conn
, "no memory");
84 substate
->dce_conn
= dce_conn
;
85 substate
->call
= NULL
;
87 DLIST_REMOVE(call
->replies
, rep
);
89 if (call
->replies
== NULL
) {
90 substate
->call
= call
;
93 substate
->iov
.iov_base
= rep
->blob
.data
;
94 substate
->iov
.iov_len
= rep
->blob
.length
;
96 subreq
= tstream_writev_queue_send(substate
,
102 dcesrv_terminate_connection(dce_conn
, "no memory");
105 tevent_req_set_callback(subreq
, dcesrv_sock_reply_done
,
109 DLIST_REMOVE(call
->conn
->call_list
, call
);
110 call
->list
= DCESRV_LIST_NONE
;
113 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
)
115 struct dcesrv_sock_reply_state
*substate
= tevent_req_callback_data(subreq
,
116 struct dcesrv_sock_reply_state
);
120 struct dcesrv_call_state
*call
= substate
->call
;
122 ret
= tstream_writev_queue_recv(subreq
, &sys_errno
);
125 status
= map_nt_error_from_unix(sys_errno
);
126 dcesrv_terminate_connection(substate
->dce_conn
, nt_errstr(status
));
130 talloc_free(substate
);
136 struct dcerpc_read_ncacn_packet_state
{
140 struct ncacn_packet
*pkt
;
143 static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context
*stream
,
146 struct iovec
**_vector
,
148 static void dcerpc_read_ncacn_packet_done(struct tevent_req
*subreq
);
150 static struct tevent_req
*dcerpc_read_ncacn_packet_send(TALLOC_CTX
*mem_ctx
,
151 struct tevent_context
*ev
,
152 struct tstream_context
*stream
)
154 struct tevent_req
*req
;
155 struct dcerpc_read_ncacn_packet_state
*state
;
156 struct tevent_req
*subreq
;
158 req
= tevent_req_create(mem_ctx
, &state
,
159 struct dcerpc_read_ncacn_packet_state
);
164 state
->buffer
= data_blob_const(NULL
, 0);
165 state
->pkt
= talloc(state
, struct ncacn_packet
);
166 if (tevent_req_nomem(state
->pkt
, req
)) {
170 subreq
= tstream_readv_pdu_send(state
, ev
,
172 dcerpc_read_ncacn_packet_next_vector
,
174 if (tevent_req_nomem(subreq
, req
)) {
177 tevent_req_set_callback(subreq
, dcerpc_read_ncacn_packet_done
, req
);
181 tevent_req_post(req
, ev
);
185 static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context
*stream
,
188 struct iovec
**_vector
,
191 struct dcerpc_read_ncacn_packet_state
*state
=
192 talloc_get_type_abort(private_data
,
193 struct dcerpc_read_ncacn_packet_state
);
194 struct iovec
*vector
;
197 if (state
->buffer
.length
== 0) {
198 /* first get enough to read the fragment length */
200 state
->buffer
.length
= DCERPC_FRAG_LEN_OFFSET
+ 2;
201 state
->buffer
.data
= talloc_array(state
, uint8_t,
202 state
->buffer
.length
);
203 if (!state
->buffer
.data
) {
206 } else if (state
->buffer
.length
== (DCERPC_FRAG_LEN_OFFSET
+ 2)) {
207 /* now read the fragment length and allocate the full buffer */
208 size_t frag_len
= dcerpc_get_frag_length(&state
->buffer
);
210 ofs
= state
->buffer
.length
;
212 state
->buffer
.data
= talloc_realloc(state
,
215 if (!state
->buffer
.data
) {
218 state
->buffer
.length
= frag_len
;
220 /* if we reach this we have a full fragment */
226 /* now create the vector that we want to be filled */
227 vector
= talloc_array(mem_ctx
, struct iovec
, 1);
232 vector
[0].iov_base
= state
->buffer
.data
+ ofs
;
233 vector
[0].iov_len
= state
->buffer
.length
- ofs
;
240 static void dcerpc_read_ncacn_packet_done(struct tevent_req
*subreq
)
242 struct tevent_req
*req
= tevent_req_callback_data(subreq
,
244 struct dcerpc_read_ncacn_packet_state
*state
= tevent_req_data(req
,
245 struct dcerpc_read_ncacn_packet_state
);
248 struct ndr_pull
*ndr
;
249 enum ndr_err_code ndr_err
;
252 ret
= tstream_readv_pdu_recv(subreq
, &sys_errno
);
255 status
= map_nt_error_from_unix(sys_errno
);
256 tevent_req_nterror(req
, status
);
260 ndr
= ndr_pull_init_blob(&state
->buffer
, state
->pkt
);
261 if (tevent_req_nomem(ndr
, req
)) {
265 if (!(CVAL(ndr
->data
, DCERPC_DREP_OFFSET
) & DCERPC_DREP_LE
)) {
266 ndr
->flags
|= LIBNDR_FLAG_BIGENDIAN
;
269 if (CVAL(ndr
->data
, DCERPC_PFC_OFFSET
) & DCERPC_PFC_FLAG_OBJECT_UUID
) {
270 ndr
->flags
|= LIBNDR_FLAG_OBJECT_PRESENT
;
273 ndr_err
= ndr_pull_ncacn_packet(ndr
, NDR_SCALARS
|NDR_BUFFERS
, state
->pkt
);
275 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
276 status
= ndr_map_error2ntstatus(ndr_err
);
277 tevent_req_nterror(req
, status
);
281 tevent_req_done(req
);
284 static NTSTATUS
dcerpc_read_ncacn_packet_recv(struct tevent_req
*req
,
286 struct ncacn_packet
**pkt
,
289 struct dcerpc_read_ncacn_packet_state
*state
= tevent_req_data(req
,
290 struct dcerpc_read_ncacn_packet_state
);
293 if (tevent_req_is_nterror(req
, &status
)) {
294 tevent_req_received(req
);
298 *pkt
= talloc_move(mem_ctx
, &state
->pkt
);
300 buffer
->data
= talloc_move(mem_ctx
, &state
->buffer
.data
);
301 buffer
->length
= state
->buffer
.length
;
304 tevent_req_received(req
);
308 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
);
310 static void dcesrv_sock_accept(struct stream_connection
*srv_conn
)
313 struct dcesrv_socket_context
*dcesrv_sock
=
314 talloc_get_type(srv_conn
->private_data
, struct dcesrv_socket_context
);
315 struct dcesrv_connection
*dcesrv_conn
= NULL
;
317 struct tevent_req
*subreq
;
318 struct loadparm_context
*lp_ctx
= dcesrv_sock
->dcesrv_ctx
->lp_ctx
;
320 if (!srv_conn
->session_info
) {
321 status
= auth_anonymous_session_info(srv_conn
,
323 &srv_conn
->session_info
);
324 if (!NT_STATUS_IS_OK(status
)) {
325 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
327 stream_terminate_connection(srv_conn
, nt_errstr(status
));
332 status
= dcesrv_endpoint_connect(dcesrv_sock
->dcesrv_ctx
,
334 dcesrv_sock
->endpoint
,
335 srv_conn
->session_info
,
339 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
341 if (!NT_STATUS_IS_OK(status
)) {
342 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
344 stream_terminate_connection(srv_conn
, nt_errstr(status
));
348 dcesrv_conn
->transport
.private_data
= srv_conn
;
349 dcesrv_conn
->transport
.report_output_data
= dcesrv_sock_report_output_data
;
351 TALLOC_FREE(srv_conn
->event
.fde
);
353 dcesrv_conn
->send_queue
= tevent_queue_create(dcesrv_conn
, "dcesrv send queue");
354 if (!dcesrv_conn
->send_queue
) {
355 status
= NT_STATUS_NO_MEMORY
;
356 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
358 stream_terminate_connection(srv_conn
, nt_errstr(status
));
362 if (dcesrv_sock
->endpoint
->ep_description
->transport
== NCACN_NP
) {
363 dcesrv_conn
->auth_state
.session_key
= dcesrv_inherited_session_key
;
364 dcesrv_conn
->stream
= talloc_move(dcesrv_conn
,
367 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
368 socket_get_fd(srv_conn
->socket
),
369 &dcesrv_conn
->stream
);
371 status
= map_nt_error_from_unix(errno
);
372 DEBUG(0, ("dcesrv_sock_accept: "
373 "failed to setup tstream: %s\n",
375 stream_terminate_connection(srv_conn
, nt_errstr(status
));
380 dcesrv_conn
->local_address
= srv_conn
->local_address
;
381 dcesrv_conn
->remote_address
= srv_conn
->remote_address
;
383 srv_conn
->private_data
= dcesrv_conn
;
385 irpc_add_name(srv_conn
->msg_ctx
, "rpc_server");
387 subreq
= dcerpc_read_ncacn_packet_send(dcesrv_conn
,
388 dcesrv_conn
->event_ctx
,
389 dcesrv_conn
->stream
);
391 status
= NT_STATUS_NO_MEMORY
;
392 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
394 stream_terminate_connection(srv_conn
, nt_errstr(status
));
397 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dcesrv_conn
);
402 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
)
404 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
405 struct dcesrv_connection
);
406 struct ncacn_packet
*pkt
;
410 status
= dcerpc_read_ncacn_packet_recv(subreq
, dce_conn
,
413 if (!NT_STATUS_IS_OK(status
)) {
414 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
418 status
= dcesrv_process_ncacn_packet(dce_conn
, pkt
, buffer
);
419 if (!NT_STATUS_IS_OK(status
)) {
420 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
424 subreq
= dcerpc_read_ncacn_packet_send(dce_conn
,
428 status
= NT_STATUS_NO_MEMORY
;
429 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
432 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dce_conn
);
435 static void dcesrv_sock_recv(struct stream_connection
*conn
, uint16_t flags
)
437 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
438 struct dcesrv_connection
);
439 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_recv triggered");
442 static void dcesrv_sock_send(struct stream_connection
*conn
, uint16_t flags
)
444 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
445 struct dcesrv_connection
);
446 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_send triggered");
450 static const struct stream_server_ops dcesrv_stream_ops
= {
452 .accept_connection
= dcesrv_sock_accept
,
453 .recv_handler
= dcesrv_sock_recv
,
454 .send_handler
= dcesrv_sock_send
,
459 static NTSTATUS
dcesrv_add_ep_unix(struct dcesrv_context
*dce_ctx
,
460 struct loadparm_context
*lp_ctx
,
461 struct dcesrv_endpoint
*e
,
462 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
464 struct dcesrv_socket_context
*dcesrv_sock
;
468 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
469 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
471 /* remember the endpoint of this socket */
472 dcesrv_sock
->endpoint
= e
;
473 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
475 status
= stream_setup_socket(event_ctx
, lp_ctx
,
476 model_ops
, &dcesrv_stream_ops
,
477 "unix", e
->ep_description
->endpoint
, &port
,
478 lp_socket_options(lp_ctx
),
480 if (!NT_STATUS_IS_OK(status
)) {
481 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
482 e
->ep_description
->endpoint
, nt_errstr(status
)));
488 static NTSTATUS
dcesrv_add_ep_ncalrpc(struct dcesrv_context
*dce_ctx
,
489 struct loadparm_context
*lp_ctx
,
490 struct dcesrv_endpoint
*e
,
491 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
493 struct dcesrv_socket_context
*dcesrv_sock
;
498 if (!e
->ep_description
->endpoint
) {
499 /* No identifier specified: use DEFAULT.
500 * DO NOT hardcode this value anywhere else. Rather, specify
501 * no endpoint and let the epmapper worry about it. */
502 e
->ep_description
->endpoint
= talloc_strdup(dce_ctx
, "DEFAULT");
505 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lp_ncalrpc_dir(lp_ctx
),
506 e
->ep_description
->endpoint
);
508 dcesrv_sock
= talloc(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(event_ctx
, lp_ctx
,
516 model_ops
, &dcesrv_stream_ops
,
517 "unix", full_path
, &port
,
518 lp_socket_options(lp_ctx
),
520 if (!NT_STATUS_IS_OK(status
)) {
521 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
522 e
->ep_description
->endpoint
, full_path
, nt_errstr(status
)));
527 static NTSTATUS
dcesrv_add_ep_np(struct dcesrv_context
*dce_ctx
,
528 struct loadparm_context
*lp_ctx
,
529 struct dcesrv_endpoint
*e
,
530 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
532 struct dcesrv_socket_context
*dcesrv_sock
;
535 if (e
->ep_description
->endpoint
== NULL
) {
536 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
537 return NT_STATUS_INVALID_PARAMETER
;
540 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
541 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
543 /* remember the endpoint of this socket */
544 dcesrv_sock
->endpoint
= e
;
545 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
547 status
= tstream_setup_named_pipe(event_ctx
, lp_ctx
,
548 model_ops
, &dcesrv_stream_ops
,
549 e
->ep_description
->endpoint
,
551 if (!NT_STATUS_IS_OK(status
)) {
552 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
553 e
->ep_description
->endpoint
, nt_errstr(status
)));
561 add a socket address to the list of events, one event per dcerpc endpoint
563 static NTSTATUS
add_socket_rpc_tcp_iface(struct dcesrv_context
*dce_ctx
, struct dcesrv_endpoint
*e
,
564 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
,
567 struct dcesrv_socket_context
*dcesrv_sock
;
571 if (e
->ep_description
->endpoint
) {
572 port
= atoi(e
->ep_description
->endpoint
);
575 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
576 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
578 /* remember the endpoint of this socket */
579 dcesrv_sock
->endpoint
= e
;
580 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
582 status
= stream_setup_socket(event_ctx
, dce_ctx
->lp_ctx
,
583 model_ops
, &dcesrv_stream_ops
,
584 "ipv4", address
, &port
,
585 lp_socket_options(dce_ctx
->lp_ctx
),
587 if (!NT_STATUS_IS_OK(status
)) {
588 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
589 address
, port
, nt_errstr(status
)));
592 if (e
->ep_description
->endpoint
== NULL
) {
593 e
->ep_description
->endpoint
= talloc_asprintf(dce_ctx
, "%d", port
);
599 static NTSTATUS
dcesrv_add_ep_tcp(struct dcesrv_context
*dce_ctx
,
600 struct loadparm_context
*lp_ctx
,
601 struct dcesrv_endpoint
*e
,
602 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
606 /* Add TCP/IP sockets */
607 if (lp_interfaces(lp_ctx
) && lp_bind_interfaces_only(lp_ctx
)) {
610 struct interface
*ifaces
;
612 load_interfaces(dce_ctx
, lp_interfaces(lp_ctx
), &ifaces
);
614 num_interfaces
= iface_count(ifaces
);
615 for(i
= 0; i
< num_interfaces
; i
++) {
616 const char *address
= iface_n_ip(ifaces
, i
);
617 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
, address
);
618 NT_STATUS_NOT_OK_RETURN(status
);
621 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
,
622 lp_socket_address(lp_ctx
));
623 NT_STATUS_NOT_OK_RETURN(status
);
629 NTSTATUS
dcesrv_add_ep(struct dcesrv_context
*dce_ctx
,
630 struct loadparm_context
*lp_ctx
,
631 struct dcesrv_endpoint
*e
,
632 struct tevent_context
*event_ctx
,
633 const struct model_ops
*model_ops
)
635 switch (e
->ep_description
->transport
) {
636 case NCACN_UNIX_STREAM
:
637 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
640 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
643 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
646 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
649 return NT_STATUS_NOT_SUPPORTED
;
654 open the dcerpc server sockets
656 static void dcesrv_task_init(struct task_server
*task
)
659 struct dcesrv_context
*dce_ctx
;
660 struct dcesrv_endpoint
*e
;
661 const struct model_ops
*model_ops
;
663 dcerpc_server_init(task
->lp_ctx
);
665 task_server_set_title(task
, "task[dcesrv]");
667 /* run the rpc server as a single process to allow for shard
668 * handles, and sharing of ldb contexts */
669 model_ops
= process_model_startup(task
->event_ctx
, "single");
670 if (!model_ops
) goto failed
;
672 status
= dcesrv_init_context(task
->event_ctx
,
674 lp_dcerpc_endpoint_servers(task
->lp_ctx
),
676 if (!NT_STATUS_IS_OK(status
)) goto failed
;
678 /* Make sure the directory for NCALRPC exists */
679 if (!directory_exist(lp_ncalrpc_dir(task
->lp_ctx
))) {
680 mkdir(lp_ncalrpc_dir(task
->lp_ctx
), 0755);
683 for (e
=dce_ctx
->endpoint_list
;e
;e
=e
->next
) {
684 status
= dcesrv_add_ep(dce_ctx
, task
->lp_ctx
, e
, task
->event_ctx
, model_ops
);
685 if (!NT_STATUS_IS_OK(status
)) goto failed
;
690 task_server_terminate(task
, "Failed to startup dcerpc server task", true);
693 NTSTATUS
server_service_rpc_init(void)
696 return register_server_service("rpc", dcesrv_task_init
);