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 "smbd/service.h"
31 #include "system/filesys.h"
32 #include "lib/socket/socket.h"
33 #include "lib/messaging/irpc.h"
34 #include "system/network.h"
35 #include "lib/socket/netif.h"
36 #include "param/param.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "librpc/rpc/dcerpc_proto.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "libcli/raw/smb.h"
41 #include "../libcli/named_pipe_auth/npa_tstream.h"
42 #include "smbd/process_model.h"
44 struct dcesrv_socket_context
{
45 const struct dcesrv_endpoint
*endpoint
;
46 struct dcesrv_context
*dcesrv_ctx
;
49 static void dcesrv_terminate_connection(struct dcesrv_connection
*dce_conn
, const char *reason
)
51 struct stream_connection
*srv_conn
;
52 srv_conn
= talloc_get_type(dce_conn
->transport
.private_data
,
53 struct stream_connection
);
55 stream_terminate_connection(srv_conn
, reason
);
58 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
);
60 struct dcesrv_sock_reply_state
{
61 struct dcesrv_connection
*dce_conn
;
62 struct dcesrv_call_state
*call
;
66 static void dcesrv_sock_report_output_data(struct dcesrv_connection
*dce_conn
)
68 struct dcesrv_call_state
*call
;
70 call
= dce_conn
->call_list
;
71 if (!call
|| !call
->replies
) {
75 while (call
->replies
) {
76 struct data_blob_list_item
*rep
= call
->replies
;
77 struct dcesrv_sock_reply_state
*substate
;
78 struct tevent_req
*subreq
;
80 substate
= talloc(call
, struct dcesrv_sock_reply_state
);
82 dcesrv_terminate_connection(dce_conn
, "no memory");
86 substate
->dce_conn
= dce_conn
;
87 substate
->call
= NULL
;
89 DLIST_REMOVE(call
->replies
, rep
);
91 if (call
->replies
== NULL
) {
92 substate
->call
= call
;
95 substate
->iov
.iov_base
= rep
->blob
.data
;
96 substate
->iov
.iov_len
= rep
->blob
.length
;
98 subreq
= tstream_writev_queue_send(substate
,
101 dce_conn
->send_queue
,
104 dcesrv_terminate_connection(dce_conn
, "no memory");
107 tevent_req_set_callback(subreq
, dcesrv_sock_reply_done
,
111 DLIST_REMOVE(call
->conn
->call_list
, call
);
112 call
->list
= DCESRV_LIST_NONE
;
115 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
)
117 struct dcesrv_sock_reply_state
*substate
= tevent_req_callback_data(subreq
,
118 struct dcesrv_sock_reply_state
);
122 struct dcesrv_call_state
*call
= substate
->call
;
124 ret
= tstream_writev_queue_recv(subreq
, &sys_errno
);
127 status
= map_nt_error_from_unix(sys_errno
);
128 dcesrv_terminate_connection(substate
->dce_conn
, nt_errstr(status
));
132 talloc_free(substate
);
138 static struct socket_address
*dcesrv_sock_get_my_addr(struct dcesrv_connection
*dcesrv_conn
, TALLOC_CTX
*mem_ctx
)
140 struct stream_connection
*srv_conn
;
141 srv_conn
= talloc_get_type(dcesrv_conn
->transport
.private_data
,
142 struct stream_connection
);
144 return socket_get_my_addr(srv_conn
->socket
, mem_ctx
);
147 static struct socket_address
*dcesrv_sock_get_peer_addr(struct dcesrv_connection
*dcesrv_conn
, TALLOC_CTX
*mem_ctx
)
149 struct stream_connection
*srv_conn
;
150 srv_conn
= talloc_get_type(dcesrv_conn
->transport
.private_data
,
151 struct stream_connection
);
153 return socket_get_peer_addr(srv_conn
->socket
, mem_ctx
);
156 struct dcerpc_read_ncacn_packet_state
{
158 struct smb_iconv_convenience
*smb_iconv_c
;
161 struct ncacn_packet
*pkt
;
164 static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context
*stream
,
167 struct iovec
**_vector
,
169 static void dcerpc_read_ncacn_packet_done(struct tevent_req
*subreq
);
171 static struct tevent_req
*dcerpc_read_ncacn_packet_send(TALLOC_CTX
*mem_ctx
,
172 struct tevent_context
*ev
,
173 struct tstream_context
*stream
,
174 struct smb_iconv_convenience
*ic
)
176 struct tevent_req
*req
;
177 struct dcerpc_read_ncacn_packet_state
*state
;
178 struct tevent_req
*subreq
;
180 req
= tevent_req_create(mem_ctx
, &state
,
181 struct dcerpc_read_ncacn_packet_state
);
186 state
->caller
.smb_iconv_c
= ic
;
187 state
->buffer
= data_blob_const(NULL
, 0);
188 state
->pkt
= talloc(state
, struct ncacn_packet
);
189 if (tevent_req_nomem(state
->pkt
, req
)) {
193 subreq
= tstream_readv_pdu_send(state
, ev
,
195 dcerpc_read_ncacn_packet_next_vector
,
197 if (tevent_req_nomem(subreq
, req
)) {
200 tevent_req_set_callback(subreq
, dcerpc_read_ncacn_packet_done
, req
);
204 tevent_req_post(req
, ev
);
208 static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context
*stream
,
211 struct iovec
**_vector
,
214 struct dcerpc_read_ncacn_packet_state
*state
=
215 talloc_get_type_abort(private_data
,
216 struct dcerpc_read_ncacn_packet_state
);
217 struct iovec
*vector
;
220 if (state
->buffer
.length
== 0) {
221 /* first get enough to read the fragment length */
223 state
->buffer
.length
= DCERPC_FRAG_LEN_OFFSET
+ 2;
224 state
->buffer
.data
= talloc_array(state
, uint8_t,
225 state
->buffer
.length
);
226 if (!state
->buffer
.data
) {
229 } else if (state
->buffer
.length
== (DCERPC_FRAG_LEN_OFFSET
+ 2)) {
230 /* now read the fragment length and allocate the full buffer */
231 size_t frag_len
= dcerpc_get_frag_length(&state
->buffer
);
233 ofs
= state
->buffer
.length
;
235 state
->buffer
.data
= talloc_realloc(state
,
238 if (!state
->buffer
.data
) {
241 state
->buffer
.length
= frag_len
;
243 /* if we reach this we have a full fragment */
249 /* now create the vector that we want to be filled */
250 vector
= talloc_array(mem_ctx
, struct iovec
, 1);
255 vector
[0].iov_base
= state
->buffer
.data
+ ofs
;
256 vector
[0].iov_len
= state
->buffer
.length
- ofs
;
263 static void dcerpc_read_ncacn_packet_done(struct tevent_req
*subreq
)
265 struct tevent_req
*req
= tevent_req_callback_data(subreq
,
267 struct dcerpc_read_ncacn_packet_state
*state
= tevent_req_data(req
,
268 struct dcerpc_read_ncacn_packet_state
);
271 struct ndr_pull
*ndr
;
272 enum ndr_err_code ndr_err
;
275 ret
= tstream_readv_pdu_recv(subreq
, &sys_errno
);
278 status
= map_nt_error_from_unix(sys_errno
);
279 tevent_req_nterror(req
, status
);
283 ndr
= ndr_pull_init_blob(&state
->buffer
,
285 state
->caller
.smb_iconv_c
);
286 if (tevent_req_nomem(ndr
, req
)) {
290 if (!(CVAL(ndr
->data
, DCERPC_DREP_OFFSET
) & DCERPC_DREP_LE
)) {
291 ndr
->flags
|= LIBNDR_FLAG_BIGENDIAN
;
294 if (CVAL(ndr
->data
, DCERPC_PFC_OFFSET
) & DCERPC_PFC_FLAG_OBJECT_UUID
) {
295 ndr
->flags
|= LIBNDR_FLAG_OBJECT_PRESENT
;
298 ndr_err
= ndr_pull_ncacn_packet(ndr
, NDR_SCALARS
|NDR_BUFFERS
, state
->pkt
);
300 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
301 status
= ndr_map_error2ntstatus(ndr_err
);
302 tevent_req_nterror(req
, status
);
306 tevent_req_done(req
);
309 static NTSTATUS
dcerpc_read_ncacn_packet_recv(struct tevent_req
*req
,
311 struct ncacn_packet
**pkt
,
314 struct dcerpc_read_ncacn_packet_state
*state
= tevent_req_data(req
,
315 struct dcerpc_read_ncacn_packet_state
);
318 if (tevent_req_is_nterror(req
, &status
)) {
319 tevent_req_received(req
);
323 *pkt
= talloc_move(mem_ctx
, &state
->pkt
);
325 buffer
->data
= talloc_move(mem_ctx
, &state
->buffer
.data
);
326 buffer
->length
= state
->buffer
.length
;
329 tevent_req_received(req
);
333 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
);
335 static void dcesrv_sock_accept(struct stream_connection
*srv_conn
)
338 struct dcesrv_socket_context
*dcesrv_sock
=
339 talloc_get_type(srv_conn
->private_data
, struct dcesrv_socket_context
);
340 struct dcesrv_connection
*dcesrv_conn
= NULL
;
342 struct tevent_req
*subreq
;
343 struct loadparm_context
*lp_ctx
= dcesrv_sock
->dcesrv_ctx
->lp_ctx
;
345 if (!srv_conn
->session_info
) {
346 status
= auth_anonymous_session_info(srv_conn
,
349 &srv_conn
->session_info
);
350 if (!NT_STATUS_IS_OK(status
)) {
351 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
353 stream_terminate_connection(srv_conn
, nt_errstr(status
));
358 status
= dcesrv_endpoint_connect(dcesrv_sock
->dcesrv_ctx
,
360 dcesrv_sock
->endpoint
,
361 srv_conn
->session_info
,
365 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
367 if (!NT_STATUS_IS_OK(status
)) {
368 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
370 stream_terminate_connection(srv_conn
, nt_errstr(status
));
374 dcesrv_conn
->transport
.private_data
= srv_conn
;
375 dcesrv_conn
->transport
.report_output_data
= dcesrv_sock_report_output_data
;
376 dcesrv_conn
->transport
.get_my_addr
= dcesrv_sock_get_my_addr
;
377 dcesrv_conn
->transport
.get_peer_addr
= dcesrv_sock_get_peer_addr
;
379 TALLOC_FREE(srv_conn
->event
.fde
);
381 dcesrv_conn
->send_queue
= tevent_queue_create(dcesrv_conn
, "dcesrv send queue");
382 if (!dcesrv_conn
->send_queue
) {
383 status
= NT_STATUS_NO_MEMORY
;
384 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
386 stream_terminate_connection(srv_conn
, nt_errstr(status
));
390 if (dcesrv_sock
->endpoint
->ep_description
->transport
== NCACN_NP
) {
391 dcesrv_conn
->auth_state
.session_key
= dcesrv_inherited_session_key
;
392 ret
= tstream_npa_existing_socket(dcesrv_conn
,
393 socket_get_fd(srv_conn
->socket
),
394 FILE_TYPE_MESSAGE_MODE_PIPE
,
395 &dcesrv_conn
->stream
);
397 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
398 socket_get_fd(srv_conn
->socket
),
399 &dcesrv_conn
->stream
);
402 status
= map_nt_error_from_unix(errno
);
403 DEBUG(0,("dcesrv_sock_accept: failed to setup tstream: %s\n",
405 stream_terminate_connection(srv_conn
, nt_errstr(status
));
409 srv_conn
->private_data
= dcesrv_conn
;
411 irpc_add_name(srv_conn
->msg_ctx
, "rpc_server");
413 subreq
= dcerpc_read_ncacn_packet_send(dcesrv_conn
,
414 dcesrv_conn
->event_ctx
,
416 lp_iconv_convenience(lp_ctx
));
418 status
= NT_STATUS_NO_MEMORY
;
419 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
421 stream_terminate_connection(srv_conn
, nt_errstr(status
));
424 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dcesrv_conn
);
429 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
)
431 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
432 struct dcesrv_connection
);
433 struct ncacn_packet
*pkt
;
436 struct loadparm_context
*lp_ctx
= dce_conn
->dce_ctx
->lp_ctx
;
438 status
= dcerpc_read_ncacn_packet_recv(subreq
, dce_conn
,
441 if (!NT_STATUS_IS_OK(status
)) {
442 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
446 status
= dcesrv_process_ncacn_packet(dce_conn
, pkt
, buffer
);
447 if (!NT_STATUS_IS_OK(status
)) {
448 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
452 subreq
= dcerpc_read_ncacn_packet_send(dce_conn
,
455 lp_iconv_convenience(lp_ctx
));
457 status
= NT_STATUS_NO_MEMORY
;
458 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
461 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dce_conn
);
464 static void dcesrv_sock_recv(struct stream_connection
*conn
, uint16_t flags
)
466 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
467 struct dcesrv_connection
);
468 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_recv triggered");
471 static void dcesrv_sock_send(struct stream_connection
*conn
, uint16_t flags
)
473 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
474 struct dcesrv_connection
);
475 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_send triggered");
479 static const struct stream_server_ops dcesrv_stream_ops
= {
481 .accept_connection
= dcesrv_sock_accept
,
482 .recv_handler
= dcesrv_sock_recv
,
483 .send_handler
= dcesrv_sock_send
,
488 static NTSTATUS
dcesrv_add_ep_unix(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
;
497 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
498 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
500 /* remember the endpoint of this socket */
501 dcesrv_sock
->endpoint
= e
;
502 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
504 status
= stream_setup_socket(event_ctx
, lp_ctx
,
505 model_ops
, &dcesrv_stream_ops
,
506 "unix", e
->ep_description
->endpoint
, &port
,
507 lp_socket_options(lp_ctx
),
509 if (!NT_STATUS_IS_OK(status
)) {
510 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
511 e
->ep_description
->endpoint
, nt_errstr(status
)));
517 static NTSTATUS
dcesrv_add_ep_ncalrpc(struct dcesrv_context
*dce_ctx
,
518 struct loadparm_context
*lp_ctx
,
519 struct dcesrv_endpoint
*e
,
520 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
522 struct dcesrv_socket_context
*dcesrv_sock
;
527 if (!e
->ep_description
->endpoint
) {
528 /* No identifier specified: use DEFAULT.
529 * DO NOT hardcode this value anywhere else. Rather, specify
530 * no endpoint and let the epmapper worry about it. */
531 e
->ep_description
->endpoint
= talloc_strdup(dce_ctx
, "DEFAULT");
534 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lp_ncalrpc_dir(lp_ctx
),
535 e
->ep_description
->endpoint
);
537 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
538 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
540 /* remember the endpoint of this socket */
541 dcesrv_sock
->endpoint
= e
;
542 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
544 status
= stream_setup_socket(event_ctx
, lp_ctx
,
545 model_ops
, &dcesrv_stream_ops
,
546 "unix", full_path
, &port
,
547 lp_socket_options(lp_ctx
),
549 if (!NT_STATUS_IS_OK(status
)) {
550 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
551 e
->ep_description
->endpoint
, full_path
, nt_errstr(status
)));
556 static NTSTATUS
dcesrv_add_ep_np(struct dcesrv_context
*dce_ctx
,
557 struct loadparm_context
*lp_ctx
,
558 struct dcesrv_endpoint
*e
,
559 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
561 struct dcesrv_socket_context
*dcesrv_sock
;
564 if (e
->ep_description
->endpoint
== NULL
) {
565 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
566 return NT_STATUS_INVALID_PARAMETER
;
569 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
570 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
572 /* remember the endpoint of this socket */
573 dcesrv_sock
->endpoint
= e
;
574 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
576 status
= stream_setup_named_pipe(event_ctx
, lp_ctx
,
577 model_ops
, &dcesrv_stream_ops
,
578 e
->ep_description
->endpoint
, dcesrv_sock
);
579 if (!NT_STATUS_IS_OK(status
)) {
580 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
581 e
->ep_description
->endpoint
, nt_errstr(status
)));
589 add a socket address to the list of events, one event per dcerpc endpoint
591 static NTSTATUS
add_socket_rpc_tcp_iface(struct dcesrv_context
*dce_ctx
, struct dcesrv_endpoint
*e
,
592 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
,
595 struct dcesrv_socket_context
*dcesrv_sock
;
599 if (e
->ep_description
->endpoint
) {
600 port
= atoi(e
->ep_description
->endpoint
);
603 dcesrv_sock
= talloc(event_ctx
, struct dcesrv_socket_context
);
604 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
606 /* remember the endpoint of this socket */
607 dcesrv_sock
->endpoint
= e
;
608 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
610 status
= stream_setup_socket(event_ctx
, dce_ctx
->lp_ctx
,
611 model_ops
, &dcesrv_stream_ops
,
612 "ipv4", address
, &port
,
613 lp_socket_options(dce_ctx
->lp_ctx
),
615 if (!NT_STATUS_IS_OK(status
)) {
616 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
617 address
, port
, nt_errstr(status
)));
620 if (e
->ep_description
->endpoint
== NULL
) {
621 e
->ep_description
->endpoint
= talloc_asprintf(dce_ctx
, "%d", port
);
627 static NTSTATUS
dcesrv_add_ep_tcp(struct dcesrv_context
*dce_ctx
,
628 struct loadparm_context
*lp_ctx
,
629 struct dcesrv_endpoint
*e
,
630 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
634 /* Add TCP/IP sockets */
635 if (lp_interfaces(lp_ctx
) && lp_bind_interfaces_only(lp_ctx
)) {
638 struct interface
*ifaces
;
640 load_interfaces(dce_ctx
, lp_interfaces(lp_ctx
), &ifaces
);
642 num_interfaces
= iface_count(ifaces
);
643 for(i
= 0; i
< num_interfaces
; i
++) {
644 const char *address
= iface_n_ip(ifaces
, i
);
645 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
, address
);
646 NT_STATUS_NOT_OK_RETURN(status
);
649 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
,
650 lp_socket_address(lp_ctx
));
651 NT_STATUS_NOT_OK_RETURN(status
);
657 NTSTATUS
dcesrv_add_ep(struct dcesrv_context
*dce_ctx
,
658 struct loadparm_context
*lp_ctx
,
659 struct dcesrv_endpoint
*e
,
660 struct tevent_context
*event_ctx
,
661 const struct model_ops
*model_ops
)
663 switch (e
->ep_description
->transport
) {
664 case NCACN_UNIX_STREAM
:
665 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
668 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
671 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
674 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
677 return NT_STATUS_NOT_SUPPORTED
;
682 open the dcerpc server sockets
684 static void dcesrv_task_init(struct task_server
*task
)
687 struct dcesrv_context
*dce_ctx
;
688 struct dcesrv_endpoint
*e
;
689 const struct model_ops
*model_ops
;
691 dcerpc_server_init(task
->lp_ctx
);
693 task_server_set_title(task
, "task[dcesrv]");
695 /* run the rpc server as a single process to allow for shard
696 * handles, and sharing of ldb contexts */
697 model_ops
= process_model_startup(task
->event_ctx
, "single");
698 if (!model_ops
) goto failed
;
700 status
= dcesrv_init_context(task
->event_ctx
,
702 lp_dcerpc_endpoint_servers(task
->lp_ctx
),
704 if (!NT_STATUS_IS_OK(status
)) goto failed
;
706 /* Make sure the directory for NCALRPC exists */
707 if (!directory_exist(lp_ncalrpc_dir(task
->lp_ctx
))) {
708 mkdir(lp_ncalrpc_dir(task
->lp_ctx
), 0755);
711 for (e
=dce_ctx
->endpoint_list
;e
;e
=e
->next
) {
712 status
= dcesrv_add_ep(dce_ctx
, task
->lp_ctx
, e
, task
->event_ctx
, model_ops
);
713 if (!NT_STATUS_IS_OK(status
)) goto failed
;
718 task_server_terminate(task
, "Failed to startup dcerpc server task", true);
721 NTSTATUS
server_service_rpc_init(void)
724 return register_server_service("rpc", dcesrv_task_init
);