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
= (void *) 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 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
);
138 static void dcesrv_sock_accept(struct stream_connection
*srv_conn
)
141 struct dcesrv_socket_context
*dcesrv_sock
=
142 talloc_get_type(srv_conn
->private_data
, struct dcesrv_socket_context
);
143 struct dcesrv_connection
*dcesrv_conn
= NULL
;
145 struct tevent_req
*subreq
;
146 struct loadparm_context
*lp_ctx
= dcesrv_sock
->dcesrv_ctx
->lp_ctx
;
148 if (!srv_conn
->session_info
) {
149 status
= auth_anonymous_session_info(srv_conn
,
151 &srv_conn
->session_info
);
152 if (!NT_STATUS_IS_OK(status
)) {
153 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
155 stream_terminate_connection(srv_conn
, nt_errstr(status
));
160 status
= dcesrv_endpoint_connect(dcesrv_sock
->dcesrv_ctx
,
162 dcesrv_sock
->endpoint
,
163 srv_conn
->session_info
,
167 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
169 if (!NT_STATUS_IS_OK(status
)) {
170 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
172 stream_terminate_connection(srv_conn
, nt_errstr(status
));
176 dcesrv_conn
->transport
.private_data
= srv_conn
;
177 dcesrv_conn
->transport
.report_output_data
= dcesrv_sock_report_output_data
;
179 TALLOC_FREE(srv_conn
->event
.fde
);
181 dcesrv_conn
->send_queue
= tevent_queue_create(dcesrv_conn
, "dcesrv send queue");
182 if (!dcesrv_conn
->send_queue
) {
183 status
= NT_STATUS_NO_MEMORY
;
184 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
186 stream_terminate_connection(srv_conn
, nt_errstr(status
));
190 if (dcesrv_sock
->endpoint
->ep_description
->transport
== NCACN_NP
) {
191 dcesrv_conn
->auth_state
.session_key
= dcesrv_inherited_session_key
;
192 dcesrv_conn
->stream
= talloc_move(dcesrv_conn
,
195 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
196 socket_get_fd(srv_conn
->socket
),
197 &dcesrv_conn
->stream
);
199 status
= map_nt_error_from_unix(errno
);
200 DEBUG(0, ("dcesrv_sock_accept: "
201 "failed to setup tstream: %s\n",
203 stream_terminate_connection(srv_conn
, nt_errstr(status
));
208 dcesrv_conn
->local_address
= srv_conn
->local_address
;
209 dcesrv_conn
->remote_address
= srv_conn
->remote_address
;
211 srv_conn
->private_data
= dcesrv_conn
;
213 irpc_add_name(srv_conn
->msg_ctx
, "rpc_server");
215 subreq
= dcerpc_read_ncacn_packet_send(dcesrv_conn
,
216 dcesrv_conn
->event_ctx
,
217 dcesrv_conn
->stream
);
219 status
= NT_STATUS_NO_MEMORY
;
220 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
222 stream_terminate_connection(srv_conn
, nt_errstr(status
));
225 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dcesrv_conn
);
230 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
)
232 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
233 struct dcesrv_connection
);
234 struct ncacn_packet
*pkt
;
238 status
= dcerpc_read_ncacn_packet_recv(subreq
, dce_conn
,
241 if (!NT_STATUS_IS_OK(status
)) {
242 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
246 status
= dcesrv_process_ncacn_packet(dce_conn
, pkt
, buffer
);
247 if (!NT_STATUS_IS_OK(status
)) {
248 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
252 subreq
= dcerpc_read_ncacn_packet_send(dce_conn
,
256 status
= NT_STATUS_NO_MEMORY
;
257 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
260 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dce_conn
);
263 static void dcesrv_sock_recv(struct stream_connection
*conn
, uint16_t flags
)
265 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
266 struct dcesrv_connection
);
267 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_recv triggered");
270 static void dcesrv_sock_send(struct stream_connection
*conn
, uint16_t flags
)
272 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
273 struct dcesrv_connection
);
274 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_send triggered");
278 static const struct stream_server_ops dcesrv_stream_ops
= {
280 .accept_connection
= dcesrv_sock_accept
,
281 .recv_handler
= dcesrv_sock_recv
,
282 .send_handler
= dcesrv_sock_send
,
287 static NTSTATUS
dcesrv_add_ep_unix(struct dcesrv_context
*dce_ctx
,
288 struct loadparm_context
*lp_ctx
,
289 struct dcesrv_endpoint
*e
,
290 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
292 struct dcesrv_socket_context
*dcesrv_sock
;
296 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
297 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
299 /* remember the endpoint of this socket */
300 dcesrv_sock
->endpoint
= e
;
301 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
303 status
= stream_setup_socket(event_ctx
, lp_ctx
,
304 model_ops
, &dcesrv_stream_ops
,
305 "unix", e
->ep_description
->endpoint
, &port
,
306 lpcfg_socket_options(lp_ctx
),
308 if (!NT_STATUS_IS_OK(status
)) {
309 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
310 e
->ep_description
->endpoint
, nt_errstr(status
)));
316 static NTSTATUS
dcesrv_add_ep_ncalrpc(struct dcesrv_context
*dce_ctx
,
317 struct loadparm_context
*lp_ctx
,
318 struct dcesrv_endpoint
*e
,
319 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
321 struct dcesrv_socket_context
*dcesrv_sock
;
326 if (!e
->ep_description
->endpoint
) {
327 /* No identifier specified: use DEFAULT.
328 * DO NOT hardcode this value anywhere else. Rather, specify
329 * no endpoint and let the epmapper worry about it. */
330 e
->ep_description
->endpoint
= talloc_strdup(dce_ctx
, "DEFAULT");
333 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx
),
334 e
->ep_description
->endpoint
);
336 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
337 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
339 /* remember the endpoint of this socket */
340 dcesrv_sock
->endpoint
= e
;
341 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
343 status
= stream_setup_socket(event_ctx
, lp_ctx
,
344 model_ops
, &dcesrv_stream_ops
,
345 "unix", full_path
, &port
,
346 lpcfg_socket_options(lp_ctx
),
348 if (!NT_STATUS_IS_OK(status
)) {
349 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
350 e
->ep_description
->endpoint
, full_path
, nt_errstr(status
)));
355 static NTSTATUS
dcesrv_add_ep_np(struct dcesrv_context
*dce_ctx
,
356 struct loadparm_context
*lp_ctx
,
357 struct dcesrv_endpoint
*e
,
358 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
360 struct dcesrv_socket_context
*dcesrv_sock
;
363 if (e
->ep_description
->endpoint
== NULL
) {
364 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
365 return NT_STATUS_INVALID_PARAMETER
;
368 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
369 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
371 /* remember the endpoint of this socket */
372 dcesrv_sock
->endpoint
= e
;
373 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
375 status
= tstream_setup_named_pipe(event_ctx
, lp_ctx
,
376 model_ops
, &dcesrv_stream_ops
,
377 e
->ep_description
->endpoint
,
379 if (!NT_STATUS_IS_OK(status
)) {
380 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
381 e
->ep_description
->endpoint
, nt_errstr(status
)));
389 add a socket address to the list of events, one event per dcerpc endpoint
391 static NTSTATUS
add_socket_rpc_tcp_iface(struct dcesrv_context
*dce_ctx
, struct dcesrv_endpoint
*e
,
392 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
,
395 struct dcesrv_socket_context
*dcesrv_sock
;
399 if (e
->ep_description
->endpoint
) {
400 port
= atoi(e
->ep_description
->endpoint
);
403 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
404 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
406 /* remember the endpoint of this socket */
407 dcesrv_sock
->endpoint
= e
;
408 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
410 status
= stream_setup_socket(event_ctx
, dce_ctx
->lp_ctx
,
411 model_ops
, &dcesrv_stream_ops
,
412 "ipv4", address
, &port
,
413 lpcfg_socket_options(dce_ctx
->lp_ctx
),
415 if (!NT_STATUS_IS_OK(status
)) {
416 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
417 address
, port
, nt_errstr(status
)));
420 if (e
->ep_description
->endpoint
== NULL
) {
421 e
->ep_description
->endpoint
= talloc_asprintf(dce_ctx
, "%d", port
);
427 static NTSTATUS
dcesrv_add_ep_tcp(struct dcesrv_context
*dce_ctx
,
428 struct loadparm_context
*lp_ctx
,
429 struct dcesrv_endpoint
*e
,
430 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
434 /* Add TCP/IP sockets */
435 if (lpcfg_interfaces(lp_ctx
) && lpcfg_bind_interfaces_only(lp_ctx
)) {
438 struct interface
*ifaces
;
440 load_interfaces(dce_ctx
, lpcfg_interfaces(lp_ctx
), &ifaces
);
442 num_interfaces
= iface_count(ifaces
);
443 for(i
= 0; i
< num_interfaces
; i
++) {
444 const char *address
= iface_n_ip(ifaces
, i
);
445 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
, address
);
446 NT_STATUS_NOT_OK_RETURN(status
);
449 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
,
450 lpcfg_socket_address(lp_ctx
));
451 NT_STATUS_NOT_OK_RETURN(status
);
457 NTSTATUS
dcesrv_add_ep(struct dcesrv_context
*dce_ctx
,
458 struct loadparm_context
*lp_ctx
,
459 struct dcesrv_endpoint
*e
,
460 struct tevent_context
*event_ctx
,
461 const struct model_ops
*model_ops
)
463 switch (e
->ep_description
->transport
) {
464 case NCACN_UNIX_STREAM
:
465 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
468 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
471 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
474 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
477 return NT_STATUS_NOT_SUPPORTED
;
482 open the dcerpc server sockets
484 static void dcesrv_task_init(struct task_server
*task
)
487 struct dcesrv_context
*dce_ctx
;
488 struct dcesrv_endpoint
*e
;
489 const struct model_ops
*model_ops
;
491 dcerpc_server_init(task
->lp_ctx
);
493 task_server_set_title(task
, "task[dcesrv]");
495 /* run the rpc server as a single process to allow for shard
496 * handles, and sharing of ldb contexts */
497 model_ops
= process_model_startup(task
->event_ctx
, "single");
498 if (!model_ops
) goto failed
;
500 status
= dcesrv_init_context(task
->event_ctx
,
502 lpcfg_dcerpc_endpoint_servers(task
->lp_ctx
),
504 if (!NT_STATUS_IS_OK(status
)) goto failed
;
506 /* Make sure the directory for NCALRPC exists */
507 if (!directory_exist(lpcfg_ncalrpc_dir(task
->lp_ctx
))) {
508 mkdir(lpcfg_ncalrpc_dir(task
->lp_ctx
), 0755);
511 for (e
=dce_ctx
->endpoint_list
;e
;e
=e
->next
) {
512 status
= dcesrv_add_ep(dce_ctx
, task
->lp_ctx
, e
, task
->event_ctx
, model_ops
);
513 if (!NT_STATUS_IS_OK(status
)) goto failed
;
518 task_server_terminate(task
, "Failed to startup dcerpc server task", true);
521 NTSTATUS
server_service_rpc_init(void)
524 return register_server_service("rpc", dcesrv_task_init
);