2 Unix SMB/Netbios implementation.
3 Generic infrstructure for RPC Daemons
4 Copyright (C) Simo Sorce 2010
5 Copyright (C) Andrew Bartlett 2011
6 Copyright (C) Andreas Schneider 2011
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/rpc_pipes.h"
24 #include "rpc_server/rpc_server.h"
25 #include "rpc_server/rpc_config.h"
27 #include "librpc/gen_ndr/netlogon.h"
28 #include "librpc/gen_ndr/auth.h"
29 #include "lib/tsocket/tsocket.h"
30 #include "libcli/named_pipe_auth/npa_tstream.h"
31 #include "../auth/auth_sam_reply.h"
33 #include "rpc_server/rpc_ncacn_np.h"
34 #include "rpc_server/srv_pipe_hnd.h"
35 #include "rpc_server/srv_pipe.h"
37 /* Creates a pipes_struct and initializes it with the information
38 * sent from the client */
39 int make_server_pipes_struct(TALLOC_CTX
*mem_ctx
,
40 struct messaging_context
*msg_ctx
,
41 const char *pipe_name
,
42 enum dcerpc_transport_t transport
,
43 const struct tsocket_address
*remote_address
,
44 const struct tsocket_address
*local_address
,
45 struct auth_session_info
**psession_info
,
46 struct pipes_struct
**_p
,
49 struct auth_session_info
*session_info
= *psession_info
;
50 struct pipes_struct
*p
;
53 ret
= make_base_pipes_struct(mem_ctx
, msg_ctx
, pipe_name
,
54 transport
, RPC_LITTLE_ENDIAN
,
55 remote_address
, local_address
, &p
);
61 if ((session_info
->unix_token
== NULL
) ||
62 (session_info
->unix_info
== NULL
) ||
63 (session_info
->security_token
== NULL
)) {
64 DBG_ERR("Supplied session_info was incomplete!\n");
70 /* Don't call create_local_token(), we already have the full details here */
71 p
->session_info
= talloc_move(p
, psession_info
);
77 /* Start listening on the appropriate unix socket and setup all is needed to
78 * dispatch requests to the pipes rpc implementation */
80 struct dcerpc_ncacn_listen_state
{
81 struct ndr_syntax_id syntax_id
;
89 struct tevent_context
*ev_ctx
;
90 struct messaging_context
*msg_ctx
;
91 dcerpc_ncacn_disconnect_fn disconnect_fn
;
94 static void dcesrv_ncacn_np_listener(struct tevent_context
*ev
,
95 struct tevent_fd
*fde
,
99 NTSTATUS
dcesrv_create_ncacn_np_socket(const char *pipe_name
, int *out_fd
)
106 * As lp_ncalrpc_dir() should have 0755, but
107 * lp_ncalrpc_dir()/np should have 0700, we need to
108 * create lp_ncalrpc_dir() first.
110 if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
111 status
= map_nt_error_from_unix_common(errno
);
112 DBG_ERR("Failed to create pipe directory %s - %s\n",
113 lp_ncalrpc_dir(), strerror(errno
));
117 np_dir
= talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
119 status
= NT_STATUS_NO_MEMORY
;
120 DBG_ERR("Out of memory\n");
124 if (!directory_create_or_exist_strict(np_dir
, geteuid(), 0700)) {
125 status
= map_nt_error_from_unix_common(errno
);
126 DBG_ERR("Failed to create pipe directory %s - %s\n",
127 np_dir
, strerror(errno
));
131 fd
= create_pipe_sock(np_dir
, pipe_name
, 0700);
133 status
= map_nt_error_from_unix_common(errno
);
134 DBG_ERR("Failed to create ncacn_np socket! '%s/%s': %s\n",
135 np_dir
, pipe_name
, strerror(errno
));
139 DBG_DEBUG("Opened pipe socket fd %d for %s\n", fd
, pipe_name
);
143 status
= NT_STATUS_OK
;
150 NTSTATUS
dcesrv_setup_ncacn_np_socket(const char *pipe_name
,
151 struct tevent_context
*ev_ctx
,
152 struct messaging_context
*msg_ctx
)
154 struct dcerpc_ncacn_listen_state
*state
;
155 struct tevent_fd
*fde
;
159 state
= talloc_zero(ev_ctx
, struct dcerpc_ncacn_listen_state
);
161 DBG_ERR("Out of memory\n");
162 return NT_STATUS_NO_MEMORY
;
165 state
->ep
.name
= talloc_strdup(state
, pipe_name
);
166 if (state
->ep
.name
== NULL
) {
167 DBG_ERR("Out of memory\n");
168 status
= NT_STATUS_NO_MEMORY
;
171 status
= dcesrv_create_ncacn_np_socket(pipe_name
, &state
->fd
);
172 if (!NT_STATUS_IS_OK(status
)) {
176 rc
= listen(state
->fd
, 5);
178 status
= map_nt_error_from_unix_common(errno
);
179 DBG_ERR("Failed to listen on ncacn_np socket %s: %s\n",
180 pipe_name
, strerror(errno
));
184 state
->ev_ctx
= ev_ctx
;
185 state
->msg_ctx
= msg_ctx
;
187 DBG_DEBUG("Opened pipe socket fd %d for %s\n",
188 state
->fd
, pipe_name
);
191 fde
= tevent_add_fd(ev_ctx
,
192 state
, state
->fd
, TEVENT_FD_READ
,
193 dcesrv_ncacn_np_listener
, state
);
198 status
= map_nt_error_from_unix_common(errno
);
199 DBG_ERR("Failed to add event handler for ncacn_np: %s\n",
204 tevent_fd_set_auto_close(fde
);
208 if (state
->fd
!= -1) {
215 static void dcesrv_ncacn_np_listener(struct tevent_context
*ev
,
216 struct tevent_fd
*fde
,
220 struct dcerpc_ncacn_listen_state
*state
=
221 talloc_get_type_abort(private_data
,
222 struct dcerpc_ncacn_listen_state
);
223 struct samba_sockaddr addr
= {
224 .sa_socklen
= sizeof(struct sockaddr_un
),
228 /* TODO: should we have a limit to the number of clients ? */
230 sd
= accept(state
->fd
, &addr
.u
.sa
, &addr
.sa_socklen
);
233 if (errno
!= EINTR
) {
234 DEBUG(6, ("Failed to get a valid socket [%s]\n",
239 smb_set_close_on_exec(sd
);
241 DBG_DEBUG("Accepted ncacn_np socket %s (fd: %d)\n",
242 addr
.u
.un
.sun_path
, sd
);
244 named_pipe_accept_function(state
->ev_ctx
,
251 /* This is the core of the rpc server.
252 * Accepts connections from clients and process requests using the appropriate
253 * dispatcher table. */
255 static int named_pipe_destructor(struct named_pipe_client
*npc
)
258 npc
->term_fn(npc
->private_data
);
263 struct named_pipe_client
*named_pipe_client_init(TALLOC_CTX
*mem_ctx
,
264 struct tevent_context
*ev_ctx
,
265 struct messaging_context
*msg_ctx
,
266 const char *pipe_name
,
267 named_pipe_termination_fn
*term_fn
,
269 uint16_t device_state
,
270 uint64_t allocation_size
,
273 struct named_pipe_client
*npc
;
275 npc
= talloc_zero(mem_ctx
, struct named_pipe_client
);
277 DEBUG(0, ("Out of memory!\n"));
280 talloc_set_destructor(npc
, named_pipe_destructor
);
282 npc
->pipe_name
= talloc_strdup(npc
, pipe_name
);
283 if (npc
->pipe_name
== NULL
) {
284 DEBUG(0, ("Out of memory!\n"));
290 npc
->msg_ctx
= msg_ctx
;
291 npc
->term_fn
= term_fn
;
292 npc
->private_data
= private_data
;
294 npc
->file_type
= file_type
;
295 npc
->device_state
= device_state
;
296 npc
->allocation_size
= allocation_size
;
301 static void named_pipe_accept_done(struct tevent_req
*subreq
);
303 void named_pipe_accept_function(struct tevent_context
*ev_ctx
,
304 struct messaging_context
*msg_ctx
,
305 const char *pipe_name
, int fd
,
306 named_pipe_termination_fn
*term_fn
,
309 struct named_pipe_client
*npc
;
310 struct tstream_context
*plain
;
311 struct tevent_req
*subreq
;
314 npc
= named_pipe_client_init(
320 FILE_TYPE_MESSAGE_MODE_PIPE
, /* file_type */
321 0xff | 0x0400 | 0x0100, /* device_state */
322 4096, /* allocation_size */
325 DEBUG(0, ("Out of memory!\n"));
330 /* make sure socket is in NON blocking state */
331 ret
= set_blocking(fd
, false);
333 DEBUG(2, ("Failed to make socket non-blocking\n"));
339 ret
= tstream_bsd_existing_socket(npc
, fd
, &plain
);
341 DEBUG(2, ("Failed to create tstream socket\n"));
347 subreq
= tstream_npa_accept_existing_send(npc
, npc
->ev
, plain
,
350 npc
->allocation_size
);
352 DEBUG(2, ("Failed to start async accept procedure\n"));
357 tevent_req_set_callback(subreq
, named_pipe_accept_done
, npc
);
360 static void named_pipe_packet_done(struct tevent_req
*subreq
);
362 static void named_pipe_accept_done(struct tevent_req
*subreq
)
364 struct auth_session_info_transport
*session_info_transport
;
365 struct named_pipe_client
*npc
=
366 tevent_req_callback_data(subreq
, struct named_pipe_client
);
370 ret
= tstream_npa_accept_existing_recv(subreq
, &error
, npc
,
372 &npc
->remote_client_addr
,
373 &npc
->remote_client_name
,
374 &npc
->local_server_addr
,
375 &npc
->local_server_name
,
376 &session_info_transport
);
380 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
386 npc
->session_info
= talloc_move(
387 npc
, &session_info_transport
->session_info
);
389 ret
= make_server_pipes_struct(npc
,
391 npc
->pipe_name
, NCACN_NP
,
392 npc
->remote_client_addr
,
393 npc
->local_server_addr
,
397 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
402 npc
->write_queue
= tevent_queue_create(npc
, "np_server_write_queue");
403 if (!npc
->write_queue
) {
404 DEBUG(2, ("Failed to set up write queue!\n"));
408 /* And now start receiving and processing packets */
409 subreq
= dcerpc_read_ncacn_packet_send(npc
, npc
->ev
, npc
->tstream
);
411 DEBUG(2, ("Failed to start receiving packets\n"));
414 tevent_req_set_callback(subreq
, named_pipe_packet_process
, npc
);
418 DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
419 npc
->remote_client_name
));
420 /* terminate client connection */
425 void named_pipe_packet_process(struct tevent_req
*subreq
)
427 struct named_pipe_client
*npc
=
428 tevent_req_callback_data(subreq
, struct named_pipe_client
);
429 struct _output_data
*out
= &npc
->p
->out_data
;
430 DATA_BLOB recv_buffer
= data_blob_null
;
431 struct ncacn_packet
*pkt
;
437 status
= dcerpc_read_ncacn_packet_recv(subreq
, npc
, &pkt
, &recv_buffer
);
439 if (!NT_STATUS_IS_OK(status
)) {
443 /* dcerpc_read_ncacn_packet_recv() returns a full PDU */
444 npc
->p
->in_data
.pdu_needed_len
= 0;
445 npc
->p
->in_data
.pdu
= recv_buffer
;
446 if (dcerpc_get_endian_flag(&recv_buffer
) & DCERPC_DREP_LE
) {
447 npc
->p
->endian
= RPC_LITTLE_ENDIAN
;
449 npc
->p
->endian
= RPC_BIG_ENDIAN
;
451 DEBUG(10, ("PDU is in %s Endian format!\n",
452 npc
->p
->endian
? "Big" : "Little"));
453 process_complete_pdu(npc
->p
, pkt
);
455 /* reset pipe state and free PDU */
456 npc
->p
->in_data
.pdu
.length
= 0;
457 talloc_free(recv_buffer
.data
);
460 /* this is needed because of the way DCERPC Binds work in
461 * the RPC marshalling code */
462 to_send
= out
->frag
.length
- out
->current_pdu_sent
;
465 npc
->iov
= talloc_zero(npc
, struct iovec
);
467 status
= NT_STATUS_NO_MEMORY
;
472 npc
->iov
[0].iov_base
= out
->frag
.data
473 + out
->current_pdu_sent
;
474 npc
->iov
[0].iov_len
= to_send
;
476 out
->current_pdu_sent
+= to_send
;
479 /* this condition is false for bind packets, or when we haven't
480 * yet got a full request, and need to wait for more data from
482 while (out
->data_sent_length
< out
->rdata
.length
) {
484 ok
= create_next_pdu(npc
->p
);
486 DEBUG(3, ("Failed to create next PDU!\n"));
487 status
= NT_STATUS_UNEXPECTED_IO_ERROR
;
491 npc
->iov
= talloc_realloc(npc
, npc
->iov
,
492 struct iovec
, npc
->count
+ 1);
494 status
= NT_STATUS_NO_MEMORY
;
498 npc
->iov
[npc
->count
].iov_base
= out
->frag
.data
;
499 npc
->iov
[npc
->count
].iov_len
= out
->frag
.length
;
504 /* we still don't have a complete request, go back and wait for more
506 if (npc
->count
== 0) {
507 /* Wait for the next packet */
508 subreq
= dcerpc_read_ncacn_packet_send(npc
, npc
->ev
, npc
->tstream
);
510 DEBUG(2, ("Failed to start receiving packets\n"));
511 status
= NT_STATUS_NO_MEMORY
;
514 tevent_req_set_callback(subreq
, named_pipe_packet_process
, npc
);
518 DBG_DEBUG("Sending %zu fragments in a total of %"PRIu32
" bytes\n",
520 npc
->p
->out_data
.data_sent_length
);
522 for (i
= 0; i
< npc
->count
; i
++) {
523 DBG_DEBUG("Sending PDU number: %zu, PDU Length: %zu\n",
525 npc
->iov
[i
].iov_len
);
526 dump_data(11, (const uint8_t *)npc
->iov
[i
].iov_base
,
527 npc
->iov
[i
].iov_len
);
529 subreq
= tstream_writev_queue_send(npc
,
536 DEBUG(2, ("Failed to send packet\n"));
537 status
= NT_STATUS_NO_MEMORY
;
540 tevent_req_set_callback(subreq
, named_pipe_packet_done
, npc
);
546 DEBUG(2, ("Fatal error(%s). "
547 "Terminating client(%s) connection!\n",
548 nt_errstr(status
), npc
->remote_client_name
));
549 /* terminate client connection */
554 static void named_pipe_packet_done(struct tevent_req
*subreq
)
556 struct named_pipe_client
*npc
=
557 tevent_req_callback_data(subreq
, struct named_pipe_client
);
561 ret
= tstream_writev_queue_recv(subreq
, &sys_errno
);
564 DEBUG(2, ("Writev failed!\n"));
568 if (tevent_queue_length(npc
->write_queue
) > 0) {
572 if (npc
->p
->fault_state
!= 0) {
573 DEBUG(2, ("Disconnect after fault\n"));
578 /* clear out any data that may have been left around */
580 TALLOC_FREE(npc
->iov
);
581 data_blob_free(&npc
->p
->in_data
.data
);
582 data_blob_free(&npc
->p
->out_data
.frag
);
583 data_blob_free(&npc
->p
->out_data
.rdata
);
585 talloc_free_children(npc
->p
->mem_ctx
);
587 /* Wait for the next packet */
588 subreq
= dcerpc_read_ncacn_packet_send(npc
, npc
->ev
, npc
->tstream
);
590 DEBUG(2, ("Failed to start receiving packets\n"));
594 tevent_req_set_callback(subreq
, named_pipe_packet_process
, npc
);
598 DEBUG(2, ("Fatal error(%s). "
599 "Terminating client(%s) connection!\n",
600 strerror(sys_errno
), npc
->remote_client_name
));
601 /* terminate client connection */
606 /********************************************************************
607 * Start listening on the tcp/ip socket
608 ********************************************************************/
610 static void dcesrv_ncacn_ip_tcp_listener(struct tevent_context
*ev
,
611 struct tevent_fd
*fde
,
615 NTSTATUS
dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage
*ifss
,
624 for (i
= lp_rpc_low_port(); i
<= lp_rpc_high_port(); i
++) {
625 fd
= open_socket_in(SOCK_STREAM
,
636 fd
= open_socket_in(SOCK_STREAM
,
643 DBG_ERR("Failed to create socket on port %u!\n", *port
);
644 return NT_STATUS_UNSUCCESSFUL
;
647 DBG_DEBUG("Opened ncacn_ip_tcp socket fd %d for port %u\n", fd
, *port
);
654 NTSTATUS
dcesrv_setup_ncacn_ip_tcp_socket(struct tevent_context
*ev_ctx
,
655 struct messaging_context
*msg_ctx
,
656 const struct sockaddr_storage
*ifss
,
659 struct dcerpc_ncacn_listen_state
*state
;
660 struct tevent_fd
*fde
;
664 state
= talloc_zero(ev_ctx
, struct dcerpc_ncacn_listen_state
);
666 DBG_ERR("Out of memory\n");
667 return NT_STATUS_NO_MEMORY
;
671 state
->ep
.port
= *port
;
672 state
->disconnect_fn
= NULL
;
674 status
= dcesrv_create_ncacn_ip_tcp_socket(ifss
, &state
->ep
.port
,
676 if (!NT_STATUS_IS_OK(status
)) {
680 state
->ev_ctx
= ev_ctx
;
681 state
->msg_ctx
= msg_ctx
;
683 /* ready to listen */
684 set_socket_options(state
->fd
, "SO_KEEPALIVE");
685 set_socket_options(state
->fd
, lp_socket_options());
687 /* Set server socket to non-blocking for the accept. */
688 set_blocking(state
->fd
, false);
690 rc
= listen(state
->fd
, SMBD_LISTEN_BACKLOG
);
692 status
= map_nt_error_from_unix_common(errno
);
693 DBG_ERR("Failed to listen on ncacn_ip_tcp socket: %s\n",
698 DBG_DEBUG("Opened socket fd %d for port %u\n",
699 state
->fd
, state
->ep
.port
);
702 fde
= tevent_add_fd(state
->ev_ctx
,
706 dcesrv_ncacn_ip_tcp_listener
,
712 status
= map_nt_error_from_unix_common(errno
);
713 DBG_ERR("Failed to add event handler for ncacn_ip_tcp: %s\n",
718 tevent_fd_set_auto_close(fde
);
720 *port
= state
->ep
.port
;
725 if (state
->fd
!= -1) {
733 static void dcesrv_ncacn_ip_tcp_listener(struct tevent_context
*ev
,
734 struct tevent_fd
*fde
,
738 struct dcerpc_ncacn_listen_state
*state
=
739 talloc_get_type_abort(private_data
,
740 struct dcerpc_ncacn_listen_state
);
741 struct tsocket_address
*cli_addr
= NULL
;
742 struct tsocket_address
*srv_addr
= NULL
;
743 struct samba_sockaddr addr
= {
744 .sa_socklen
= sizeof(struct sockaddr_storage
),
749 s
= accept(state
->fd
, &addr
.u
.sa
, &addr
.sa_socklen
);
751 if (errno
!= EINTR
) {
752 DBG_ERR("Failed to accept: %s\n", strerror(errno
));
756 smb_set_close_on_exec(s
);
758 rc
= tsocket_address_bsd_from_samba_sockaddr(state
, &addr
, &cli_addr
);
764 rc
= getsockname(s
, &addr
.u
.sa
, &addr
.sa_socklen
);
770 rc
= tsocket_address_bsd_from_samba_sockaddr(state
, &addr
, &srv_addr
);
776 DBG_DEBUG("Accepted ncacn_ip_tcp socket %d\n", s
);
778 dcerpc_ncacn_accept(state
->ev_ctx
,
788 /********************************************************************
789 * Start listening on the ncalrpc socket
790 ********************************************************************/
792 static void dcesrv_ncalrpc_listener(struct tevent_context
*ev
,
793 struct tevent_fd
*fde
,
797 NTSTATUS
dcesrv_create_ncalrpc_socket(const char *name
, int *out_fd
)
806 if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
807 status
= map_nt_error_from_unix_common(errno
);
808 DBG_ERR("Failed to create ncalrpc directory '%s': %s\n",
809 lp_ncalrpc_dir(), strerror(errno
));
813 fd
= create_pipe_sock(lp_ncalrpc_dir(), name
, 0755);
815 status
= map_nt_error_from_unix_common(errno
);
816 DBG_ERR("Failed to create ncalrpc socket '%s/%s': %s\n",
817 lp_ncalrpc_dir(), name
, strerror(errno
));
821 DBG_DEBUG("Opened ncalrpc socket fd '%d' for '%s/%s'\n",
822 fd
, lp_ncalrpc_dir(), name
);
832 NTSTATUS
dcesrv_setup_ncalrpc_socket(struct tevent_context
*ev_ctx
,
833 struct messaging_context
*msg_ctx
,
835 dcerpc_ncacn_disconnect_fn fn
)
837 struct dcerpc_ncacn_listen_state
*state
;
838 struct tevent_fd
*fde
;
842 state
= talloc_zero(ev_ctx
, struct dcerpc_ncacn_listen_state
);
844 DBG_ERR("Out of memory\n");
845 return NT_STATUS_NO_MEMORY
;
849 state
->disconnect_fn
= fn
;
855 state
->ep
.name
= talloc_strdup(state
, name
);
856 if (state
->ep
.name
== NULL
) {
857 DBG_ERR("Out of memory\n");
859 return NT_STATUS_NO_MEMORY
;
862 status
= dcesrv_create_ncalrpc_socket(name
, &state
->fd
);
863 if (!NT_STATUS_IS_OK(status
)) {
864 DBG_ERR("Failed to create ncalrpc socket: %s\n",
869 rc
= listen(state
->fd
, 5);
871 status
= map_nt_error_from_unix_common(errno
);
872 DBG_ERR("Failed to listen on ncalrpc socket %s: %s\n",
873 name
, strerror(errno
));
877 state
->ev_ctx
= ev_ctx
;
878 state
->msg_ctx
= msg_ctx
;
880 /* Set server socket to non-blocking for the accept. */
881 set_blocking(state
->fd
, false);
884 fde
= tevent_add_fd(state
->ev_ctx
,
888 dcesrv_ncalrpc_listener
,
894 status
= map_nt_error_from_unix_common(errno
);
895 DBG_ERR("Failed to add event handler for ncalrpc: %s\n",
900 tevent_fd_set_auto_close(fde
);
904 if (state
->fd
!= -1) {
912 static void dcesrv_ncalrpc_listener(struct tevent_context
*ev
,
913 struct tevent_fd
*fde
,
917 struct dcerpc_ncacn_listen_state
*state
=
918 talloc_get_type_abort(private_data
,
919 struct dcerpc_ncacn_listen_state
);
920 struct tsocket_address
*cli_addr
= NULL
, *srv_addr
= NULL
;
921 struct samba_sockaddr addr
= {
922 .sa_socklen
= sizeof(struct sockaddr_un
),
924 struct samba_sockaddr addr_server
= {
925 .sa_socklen
= sizeof(struct sockaddr_un
),
930 sd
= accept(state
->fd
, &addr
.u
.sa
, &addr
.sa_socklen
);
932 if (errno
!= EINTR
) {
933 DBG_ERR("Failed to accept: %s\n", strerror(errno
));
937 smb_set_close_on_exec(sd
);
939 rc
= tsocket_address_bsd_from_samba_sockaddr(state
, &addr
, &cli_addr
);
945 rc
= getsockname(sd
, &addr_server
.u
.sa
, &addr_server
.sa_socklen
);
951 rc
= tsocket_address_bsd_from_samba_sockaddr(state
,
959 DBG_DEBUG("Accepted ncalrpc socket %s (fd: %d)\n",
960 addr
.u
.un
.sun_path
, sd
);
962 dcerpc_ncacn_accept(state
->ev_ctx
,
966 cli_addr
, srv_addr
, sd
,
967 state
->disconnect_fn
);
970 struct dcerpc_ncacn_conn
{
971 enum dcerpc_transport_t transport
;
975 struct pipes_struct
*p
;
976 dcerpc_ncacn_disconnect_fn disconnect_fn
;
978 struct tevent_context
*ev_ctx
;
979 struct messaging_context
*msg_ctx
;
981 struct tstream_context
*tstream
;
982 struct tevent_queue
*send_queue
;
984 struct tsocket_address
*remote_client_addr
;
985 char *remote_client_name
;
986 struct tsocket_address
*local_server_addr
;
987 char *local_server_name
;
988 struct auth_session_info
*session_info
;
994 static void dcerpc_ncacn_packet_process(struct tevent_req
*subreq
);
995 static void dcerpc_ncacn_packet_done(struct tevent_req
*subreq
);
997 void dcerpc_ncacn_accept(struct tevent_context
*ev_ctx
,
998 struct messaging_context
*msg_ctx
,
999 enum dcerpc_transport_t transport
,
1001 struct tsocket_address
*cli_addr
,
1002 struct tsocket_address
*srv_addr
,
1004 dcerpc_ncacn_disconnect_fn fn
) {
1005 struct dcerpc_ncacn_conn
*ncacn_conn
;
1006 struct tevent_req
*subreq
;
1014 DEBUG(10, ("dcerpc_ncacn_accept\n"));
1016 ncacn_conn
= talloc_zero(ev_ctx
, struct dcerpc_ncacn_conn
);
1017 if (ncacn_conn
== NULL
) {
1018 DEBUG(0, ("Out of memory!\n"));
1023 ncacn_conn
->transport
= transport
;
1024 ncacn_conn
->ev_ctx
= ev_ctx
;
1025 ncacn_conn
->msg_ctx
= msg_ctx
;
1026 ncacn_conn
->sock
= s
;
1027 ncacn_conn
->disconnect_fn
= fn
;
1029 ncacn_conn
->remote_client_addr
= talloc_move(ncacn_conn
, &cli_addr
);
1030 if (tsocket_address_is_inet(ncacn_conn
->remote_client_addr
, "ip")) {
1031 ncacn_conn
->remote_client_name
=
1032 tsocket_address_inet_addr_string(ncacn_conn
->remote_client_addr
,
1035 ncacn_conn
->remote_client_name
=
1036 tsocket_address_unix_path(ncacn_conn
->remote_client_addr
,
1039 if (ncacn_conn
->remote_client_name
== NULL
) {
1040 DEBUG(0, ("Out of memory obtaining remote socket address as a string!\n"));
1041 talloc_free(ncacn_conn
);
1046 if (srv_addr
!= NULL
) {
1047 ncacn_conn
->local_server_addr
= talloc_move(ncacn_conn
, &srv_addr
);
1049 if (tsocket_address_is_inet(ncacn_conn
->local_server_addr
, "ip")) {
1050 ncacn_conn
->local_server_name
=
1051 tsocket_address_inet_addr_string(ncacn_conn
->local_server_addr
,
1054 ncacn_conn
->local_server_name
=
1055 tsocket_address_unix_path(ncacn_conn
->local_server_addr
,
1058 if (ncacn_conn
->local_server_name
== NULL
) {
1059 DEBUG(0, ("Out of memory obtaining local socket address as a string!\n"));
1060 talloc_free(ncacn_conn
);
1066 switch (transport
) {
1068 pipe_name
= tsocket_address_string(ncacn_conn
->remote_client_addr
,
1070 if (pipe_name
== NULL
) {
1072 talloc_free(ncacn_conn
);
1078 rc
= getpeereid(s
, &uid
, &gid
);
1080 DEBUG(2, ("Failed to get ncalrpc connecting "
1081 "uid - %s!\n", strerror(errno
)));
1083 if (uid
== sec_initial_uid()) {
1084 TALLOC_FREE(ncacn_conn
->remote_client_addr
);
1086 rc
= tsocket_address_unix_from_path(ncacn_conn
,
1087 AS_SYSTEM_MAGIC_PATH_TOKEN
,
1088 &ncacn_conn
->remote_client_addr
);
1090 DEBUG(0, ("Out of memory building magic ncalrpc_as_system path!\n"));
1091 talloc_free(ncacn_conn
);
1096 TALLOC_FREE(ncacn_conn
->remote_client_name
);
1097 ncacn_conn
->remote_client_name
1098 = tsocket_address_unix_path(ncacn_conn
->remote_client_addr
,
1100 if (ncacn_conn
->remote_client_name
== NULL
) {
1101 DEBUG(0, ("Out of memory getting magic ncalrpc_as_system string!\n"));
1102 talloc_free(ncacn_conn
);
1111 pipe_name
= talloc_strdup(ncacn_conn
,
1113 if (pipe_name
== NULL
) {
1115 talloc_free(ncacn_conn
);
1120 DEBUG(0, ("unknown dcerpc transport: %u!\n",
1122 talloc_free(ncacn_conn
);
1127 rc
= set_blocking(s
, false);
1129 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1130 talloc_free(ncacn_conn
);
1136 * As soon as we have tstream_bsd_existing_socket set up it will
1137 * take care of closing the socket.
1139 rc
= tstream_bsd_existing_socket(ncacn_conn
, s
, &ncacn_conn
->tstream
);
1141 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1142 talloc_free(ncacn_conn
);
1147 if (ncacn_conn
->session_info
== NULL
) {
1148 status
= make_session_info_anonymous(ncacn_conn
,
1149 &ncacn_conn
->session_info
);
1150 if (!NT_STATUS_IS_OK(status
)) {
1151 DEBUG(2, ("Failed to create "
1152 "make_session_info_anonymous - %s\n",
1153 nt_errstr(status
)));
1154 talloc_free(ncacn_conn
);
1159 rc
= make_server_pipes_struct(ncacn_conn
,
1160 ncacn_conn
->msg_ctx
,
1162 ncacn_conn
->transport
,
1163 ncacn_conn
->remote_client_addr
,
1164 ncacn_conn
->local_server_addr
,
1165 &ncacn_conn
->session_info
,
1169 DEBUG(2, ("Failed to create pipe struct - %s",
1170 strerror(sys_errno
)));
1171 talloc_free(ncacn_conn
);
1175 ncacn_conn
->send_queue
= tevent_queue_create(ncacn_conn
,
1176 "dcerpc send queue");
1177 if (ncacn_conn
->send_queue
== NULL
) {
1178 DEBUG(0, ("Out of memory building dcerpc send queue!\n"));
1179 talloc_free(ncacn_conn
);
1183 subreq
= dcerpc_read_ncacn_packet_send(ncacn_conn
,
1185 ncacn_conn
->tstream
);
1186 if (subreq
== NULL
) {
1187 DEBUG(2, ("Failed to send ncacn packet\n"));
1188 talloc_free(ncacn_conn
);
1192 tevent_req_set_callback(subreq
, dcerpc_ncacn_packet_process
, ncacn_conn
);
1194 DEBUG(10, ("dcerpc_ncacn_accept done\n"));
1199 static void dcerpc_ncacn_packet_process(struct tevent_req
*subreq
)
1201 struct dcerpc_ncacn_conn
*ncacn_conn
=
1202 tevent_req_callback_data(subreq
, struct dcerpc_ncacn_conn
);
1204 struct _output_data
*out
= &ncacn_conn
->p
->out_data
;
1205 DATA_BLOB recv_buffer
= data_blob_null
;
1206 struct ncacn_packet
*pkt
;
1211 status
= dcerpc_read_ncacn_packet_recv(subreq
, ncacn_conn
, &pkt
, &recv_buffer
);
1212 TALLOC_FREE(subreq
);
1213 if (!NT_STATUS_IS_OK(status
)) {
1214 if (ncacn_conn
->disconnect_fn
!= NULL
) {
1215 ok
= ncacn_conn
->disconnect_fn(ncacn_conn
->p
);
1217 DEBUG(3, ("Failed to call disconnect function\n"));
1223 /* dcerpc_read_ncacn_packet_recv() returns a full PDU */
1224 ncacn_conn
->p
->in_data
.pdu_needed_len
= 0;
1225 ncacn_conn
->p
->in_data
.pdu
= recv_buffer
;
1226 if (dcerpc_get_endian_flag(&recv_buffer
) & DCERPC_DREP_LE
) {
1227 ncacn_conn
->p
->endian
= RPC_LITTLE_ENDIAN
;
1229 ncacn_conn
->p
->endian
= RPC_BIG_ENDIAN
;
1231 DEBUG(10, ("PDU is in %s Endian format!\n",
1232 ncacn_conn
->p
->endian
? "Big" : "Little"));
1233 process_complete_pdu(ncacn_conn
->p
, pkt
);
1235 /* reset pipe state and free PDU */
1236 ncacn_conn
->p
->in_data
.pdu
.length
= 0;
1237 talloc_free(recv_buffer
.data
);
1241 * This is needed because of the way DCERPC binds work in the RPC
1244 to_send
= out
->frag
.length
- out
->current_pdu_sent
;
1247 DEBUG(10, ("Current_pdu_len = %u, "
1248 "current_pdu_sent = %u "
1249 "Returning %u bytes\n",
1250 (unsigned int)out
->frag
.length
,
1251 (unsigned int)out
->current_pdu_sent
,
1252 (unsigned int)to_send
));
1254 ncacn_conn
->iov
= talloc_zero(ncacn_conn
, struct iovec
);
1255 if (ncacn_conn
->iov
== NULL
) {
1256 status
= NT_STATUS_NO_MEMORY
;
1257 DEBUG(3, ("Out of memory!\n"));
1260 ncacn_conn
->count
= 1;
1262 ncacn_conn
->iov
[0].iov_base
= out
->frag
.data
1263 + out
->current_pdu_sent
;
1264 ncacn_conn
->iov
[0].iov_len
= to_send
;
1266 out
->current_pdu_sent
+= to_send
;
1270 * This condition is false for bind packets, or when we haven't yet got
1271 * a full request, and need to wait for more data from the client
1273 while (out
->data_sent_length
< out
->rdata
.length
) {
1274 ok
= create_next_pdu(ncacn_conn
->p
);
1276 DEBUG(3, ("Failed to create next PDU!\n"));
1277 status
= NT_STATUS_UNEXPECTED_IO_ERROR
;
1281 ncacn_conn
->iov
= talloc_realloc(ncacn_conn
,
1284 ncacn_conn
->count
+ 1);
1285 if (ncacn_conn
->iov
== NULL
) {
1286 DEBUG(3, ("Out of memory!\n"));
1287 status
= NT_STATUS_NO_MEMORY
;
1291 ncacn_conn
->iov
[ncacn_conn
->count
].iov_base
= out
->frag
.data
;
1292 ncacn_conn
->iov
[ncacn_conn
->count
].iov_len
= out
->frag
.length
;
1294 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
1295 (unsigned int) ncacn_conn
->count
,
1296 (unsigned int) ncacn_conn
->iov
[ncacn_conn
->count
].iov_len
));
1297 dump_data(11, (const uint8_t *) ncacn_conn
->iov
[ncacn_conn
->count
].iov_base
,
1298 ncacn_conn
->iov
[ncacn_conn
->count
].iov_len
);
1299 ncacn_conn
->count
++;
1303 * We still don't have a complete request, go back and wait for more
1306 if (ncacn_conn
->count
== 0) {
1307 /* Wait for the next packet */
1308 subreq
= dcerpc_read_ncacn_packet_send(ncacn_conn
,
1310 ncacn_conn
->tstream
);
1311 if (subreq
== NULL
) {
1312 DEBUG(2, ("Failed to start receiving packets\n"));
1313 status
= NT_STATUS_NO_MEMORY
;
1316 tevent_req_set_callback(subreq
, dcerpc_ncacn_packet_process
, ncacn_conn
);
1320 DEBUG(10, ("Sending a total of %u bytes\n",
1321 (unsigned int)ncacn_conn
->p
->out_data
.data_sent_length
));
1323 subreq
= tstream_writev_queue_send(ncacn_conn
,
1325 ncacn_conn
->tstream
,
1326 ncacn_conn
->send_queue
,
1329 if (subreq
== NULL
) {
1330 DEBUG(2, ("Failed to send packet\n"));
1331 status
= NT_STATUS_NO_MEMORY
;
1335 tevent_req_set_callback(subreq
, dcerpc_ncacn_packet_done
, ncacn_conn
);
1339 DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1340 ncacn_conn
->remote_client_name
, nt_errstr(status
)));
1342 /* Terminate client connection */
1343 talloc_free(ncacn_conn
);
1347 static void dcerpc_ncacn_packet_done(struct tevent_req
*subreq
)
1349 struct dcerpc_ncacn_conn
*ncacn_conn
=
1350 tevent_req_callback_data(subreq
, struct dcerpc_ncacn_conn
);
1351 NTSTATUS status
= NT_STATUS_OK
;
1355 rc
= tstream_writev_queue_recv(subreq
, &sys_errno
);
1356 TALLOC_FREE(subreq
);
1358 DEBUG(2, ("Writev failed!\n"));
1359 status
= map_nt_error_from_unix(sys_errno
);
1363 if (ncacn_conn
->p
->fault_state
!= 0) {
1364 DEBUG(2, ("Disconnect after fault\n"));
1369 /* clear out any data that may have been left around */
1370 ncacn_conn
->count
= 0;
1371 TALLOC_FREE(ncacn_conn
->iov
);
1372 data_blob_free(&ncacn_conn
->p
->in_data
.data
);
1373 data_blob_free(&ncacn_conn
->p
->out_data
.frag
);
1374 data_blob_free(&ncacn_conn
->p
->out_data
.rdata
);
1376 talloc_free_children(ncacn_conn
->p
->mem_ctx
);
1378 /* Wait for the next packet */
1379 subreq
= dcerpc_read_ncacn_packet_send(ncacn_conn
,
1381 ncacn_conn
->tstream
);
1382 if (subreq
== NULL
) {
1383 DEBUG(2, ("Failed to start receiving packets\n"));
1384 status
= NT_STATUS_NO_MEMORY
;
1388 tevent_req_set_callback(subreq
, dcerpc_ncacn_packet_process
, ncacn_conn
);
1392 DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1393 ncacn_conn
->remote_client_name
, nt_errstr(status
)));
1395 /* Terminate client connection */
1396 talloc_free(ncacn_conn
);
1400 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */