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 *session_info,
46 struct pipes_struct **_p,
49 struct pipes_struct *p;
52 ret = make_base_pipes_struct(mem_ctx, msg_ctx, pipe_name,
53 transport, RPC_LITTLE_ENDIAN,
54 remote_address, local_address, &p);
60 if (session_info->unix_token && session_info->unix_info && session_info->security_token) {
61 /* Don't call create_local_token(), we already have the full details here */
62 p->session_info = talloc_steal(p, session_info);
65 DEBUG(0, ("Supplied session_info in make_server_pipes_struct was incomplete!"));
74 /* Start listening on the appropriate unix socket and setup all is needed to
75 * dispatch requests to the pipes rpc implementation */
77 struct dcerpc_ncacn_listen_state {
78 struct ndr_syntax_id syntax_id;
86 struct tevent_context *ev_ctx;
87 struct messaging_context *msg_ctx;
88 dcerpc_ncacn_disconnect_fn disconnect_fn;
91 static void named_pipe_listener(struct tevent_context *ev,
92 struct tevent_fd *fde,
96 int create_named_pipe_socket(const char *pipe_name)
102 * As lp_ncalrpc_dir() should have 0755, but
103 * lp_ncalrpc_dir()/np should have 0700, we need to
104 * create lp_ncalrpc_dir() first.
106 if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
107 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
108 lp_ncalrpc_dir(), strerror(errno)));
112 np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
114 DEBUG(0, ("Out of memory\n"));
118 if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) {
119 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
120 np_dir, strerror(errno)));
124 fd = create_pipe_sock(np_dir, pipe_name, 0700);
126 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
131 DEBUG(10, ("Opened pipe socket fd %d for %s\n", fd, pipe_name));
138 bool setup_named_pipe_socket(const char *pipe_name,
139 struct tevent_context *ev_ctx,
140 struct messaging_context *msg_ctx)
142 struct dcerpc_ncacn_listen_state *state;
143 struct tevent_fd *fde;
146 state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
148 DEBUG(0, ("Out of memory\n"));
151 state->ep.name = talloc_strdup(state, pipe_name);
152 if (state->ep.name == NULL) {
153 DEBUG(0, ("Out of memory\n"));
156 state->fd = create_named_pipe_socket(pipe_name);
157 if (state->fd == -1) {
161 rc = listen(state->fd, 5);
163 DEBUG(0, ("Failed to listen on pipe socket %s: %s\n",
164 pipe_name, strerror(errno)));
168 state->ev_ctx = ev_ctx;
169 state->msg_ctx = msg_ctx;
171 DEBUG(10, ("Opened pipe socket fd %d for %s\n",
172 state->fd, pipe_name));
174 fde = tevent_add_fd(ev_ctx,
175 state, state->fd, TEVENT_FD_READ,
176 named_pipe_listener, state);
178 DEBUG(0, ("Failed to add event handler!\n"));
182 tevent_fd_set_auto_close(fde);
186 if (state->fd != -1) {
193 static void named_pipe_listener(struct tevent_context *ev,
194 struct tevent_fd *fde,
198 struct dcerpc_ncacn_listen_state *state =
199 talloc_get_type_abort(private_data,
200 struct dcerpc_ncacn_listen_state);
201 struct sockaddr_un sunaddr;
205 /* TODO: should we have a limit to the number of clients ? */
207 len = sizeof(sunaddr);
209 sd = accept(state->fd,
210 (struct sockaddr *)(void *)&sunaddr, &len);
213 if (errno != EINTR) {
214 DEBUG(6, ("Failed to get a valid socket [%s]\n",
219 smb_set_close_on_exec(sd);
221 DEBUG(6, ("Accepted socket %d\n", sd));
223 named_pipe_accept_function(state->ev_ctx,
230 /* This is the core of the rpc server.
231 * Accepts connections from clients and process requests using the appropriate
232 * dispatcher table. */
234 static int named_pipe_destructor(struct named_pipe_client *npc)
237 npc->term_fn(npc->private_data);
242 struct named_pipe_client *named_pipe_client_init(TALLOC_CTX *mem_ctx,
243 struct tevent_context *ev_ctx,
244 struct messaging_context *msg_ctx,
245 const char *pipe_name,
246 named_pipe_termination_fn *term_fn,
248 uint16_t device_state,
249 uint64_t allocation_size,
252 struct named_pipe_client *npc;
254 npc = talloc_zero(mem_ctx, struct named_pipe_client);
256 DEBUG(0, ("Out of memory!\n"));
259 talloc_set_destructor(npc, named_pipe_destructor);
261 npc->pipe_name = talloc_strdup(npc, pipe_name);
262 if (npc->pipe_name == NULL) {
263 DEBUG(0, ("Out of memory!\n"));
269 npc->msg_ctx = msg_ctx;
270 npc->term_fn = term_fn;
271 npc->private_data = private_data;
273 npc->file_type = file_type;
274 npc->device_state = device_state;
275 npc->allocation_size = allocation_size;
280 static void named_pipe_accept_done(struct tevent_req *subreq);
282 void named_pipe_accept_function(struct tevent_context *ev_ctx,
283 struct messaging_context *msg_ctx,
284 const char *pipe_name, int fd,
285 named_pipe_termination_fn *term_fn,
288 struct named_pipe_client *npc;
289 struct tstream_context *plain;
290 struct tevent_req *subreq;
293 npc = talloc_zero(ev_ctx, struct named_pipe_client);
295 DEBUG(0, ("Out of memory!\n"));
300 npc->pipe_name = talloc_strdup(npc, pipe_name);
301 if (npc->pipe_name == NULL) {
302 DEBUG(0, ("Out of memory!\n"));
308 npc->msg_ctx = msg_ctx;
309 npc->term_fn = term_fn;
310 npc->private_data = private_data;
312 talloc_set_destructor(npc, named_pipe_destructor);
314 /* make sure socket is in NON blocking state */
315 ret = set_blocking(fd, false);
317 DEBUG(2, ("Failed to make socket non-blocking\n"));
323 ret = tstream_bsd_existing_socket(npc, fd, &plain);
325 DEBUG(2, ("Failed to create tstream socket\n"));
331 npc->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
332 npc->device_state = 0xff | 0x0400 | 0x0100;
333 npc->allocation_size = 4096;
335 subreq = tstream_npa_accept_existing_send(npc, npc->ev, plain,
338 npc->allocation_size);
340 DEBUG(2, ("Failed to start async accept procedure\n"));
345 tevent_req_set_callback(subreq, named_pipe_accept_done, npc);
348 static void named_pipe_packet_done(struct tevent_req *subreq);
350 static void named_pipe_accept_done(struct tevent_req *subreq)
352 struct auth_session_info_transport *session_info_transport;
353 struct named_pipe_client *npc =
354 tevent_req_callback_data(subreq, struct named_pipe_client);
358 ret = tstream_npa_accept_existing_recv(subreq, &error, npc,
360 &npc->remote_client_addr,
361 &npc->remote_client_name,
362 &npc->local_server_addr,
363 &npc->local_server_name,
364 &session_info_transport);
366 npc->session_info = talloc_move(npc, &session_info_transport->session_info);
370 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
376 ret = make_server_pipes_struct(npc,
378 npc->pipe_name, NCACN_NP,
379 npc->remote_client_addr,
380 npc->local_server_addr,
384 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
389 npc->write_queue = tevent_queue_create(npc, "np_server_write_queue");
390 if (!npc->write_queue) {
391 DEBUG(2, ("Failed to set up write queue!\n"));
395 /* And now start receiving and processing packets */
396 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
398 DEBUG(2, ("Failed to start receving packets\n"));
401 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
405 DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
406 npc->remote_client_name));
407 /* terminate client connection */
412 void named_pipe_packet_process(struct tevent_req *subreq)
414 struct named_pipe_client *npc =
415 tevent_req_callback_data(subreq, struct named_pipe_client);
416 struct _output_data *out = &npc->p->out_data;
417 DATA_BLOB recv_buffer = data_blob_null;
418 struct ncacn_packet *pkt;
424 status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer);
426 if (!NT_STATUS_IS_OK(status)) {
430 /* dcerpc_read_ncacn_packet_recv() returns a full PDU */
431 npc->p->in_data.pdu_needed_len = 0;
432 npc->p->in_data.pdu = recv_buffer;
433 if (dcerpc_get_endian_flag(&recv_buffer) & DCERPC_DREP_LE) {
434 npc->p->endian = RPC_LITTLE_ENDIAN;
436 npc->p->endian = RPC_BIG_ENDIAN;
438 DEBUG(10, ("PDU is in %s Endian format!\n",
439 npc->p->endian ? "Big" : "Little"));
440 process_complete_pdu(npc->p, pkt);
442 /* reset pipe state and free PDU */
443 npc->p->in_data.pdu.length = 0;
444 talloc_free(recv_buffer.data);
447 /* this is needed because of the way DCERPC Binds work in
448 * the RPC marshalling code */
449 to_send = out->frag.length - out->current_pdu_sent;
452 npc->iov = talloc_zero(npc, struct iovec);
454 status = NT_STATUS_NO_MEMORY;
459 npc->iov[0].iov_base = out->frag.data
460 + out->current_pdu_sent;
461 npc->iov[0].iov_len = to_send;
463 out->current_pdu_sent += to_send;
466 /* this condition is false for bind packets, or when we haven't
467 * yet got a full request, and need to wait for more data from
469 while (out->data_sent_length < out->rdata.length) {
471 ok = create_next_pdu(npc->p);
473 DEBUG(3, ("Failed to create next PDU!\n"));
474 status = NT_STATUS_UNEXPECTED_IO_ERROR;
478 npc->iov = talloc_realloc(npc, npc->iov,
479 struct iovec, npc->count + 1);
481 status = NT_STATUS_NO_MEMORY;
485 npc->iov[npc->count].iov_base = out->frag.data;
486 npc->iov[npc->count].iov_len = out->frag.length;
491 /* we still don't have a complete request, go back and wait for more
493 if (npc->count == 0) {
494 /* Wait for the next packet */
495 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
497 DEBUG(2, ("Failed to start receving packets\n"));
498 status = NT_STATUS_NO_MEMORY;
501 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
505 DEBUG(10, ("Sending %u fragments in a total of %u bytes\n",
506 (unsigned int)npc->count,
507 (unsigned int)npc->p->out_data.data_sent_length));
509 for (i = 0; i < npc->count; i++) {
510 DEBUG(10, ("Sending PDU number: %d, PDU Length: %u\n",
512 (unsigned int)npc->iov[i].iov_len));
513 dump_data(11, (const uint8_t *)npc->iov[i].iov_base,
514 npc->iov[i].iov_len);
516 subreq = tstream_writev_queue_send(npc,
523 DEBUG(2, ("Failed to send packet\n"));
524 status = NT_STATUS_NO_MEMORY;
527 tevent_req_set_callback(subreq, named_pipe_packet_done, npc);
533 DEBUG(2, ("Fatal error(%s). "
534 "Terminating client(%s) connection!\n",
535 nt_errstr(status), npc->remote_client_name));
536 /* terminate client connection */
541 static void named_pipe_packet_done(struct tevent_req *subreq)
543 struct named_pipe_client *npc =
544 tevent_req_callback_data(subreq, struct named_pipe_client);
548 ret = tstream_writev_queue_recv(subreq, &sys_errno);
551 DEBUG(2, ("Writev failed!\n"));
555 if (tevent_queue_length(npc->write_queue) > 0) {
559 if (npc->p->fault_state != 0) {
560 DEBUG(2, ("Disconnect after fault\n"));
565 /* clear out any data that may have been left around */
567 TALLOC_FREE(npc->iov);
568 data_blob_free(&npc->p->in_data.data);
569 data_blob_free(&npc->p->out_data.frag);
570 data_blob_free(&npc->p->out_data.rdata);
572 talloc_free_children(npc->p->mem_ctx);
574 /* Wait for the next packet */
575 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
577 DEBUG(2, ("Failed to start receving packets\n"));
581 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
585 DEBUG(2, ("Fatal error(%s). "
586 "Terminating client(%s) connection!\n",
587 strerror(sys_errno), npc->remote_client_name));
588 /* terminate client connection */
593 /********************************************************************
594 * Start listening on the tcp/ip socket
595 ********************************************************************/
597 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
598 struct tevent_fd *fde,
602 int create_tcpip_socket(const struct sockaddr_storage *ifss, uint16_t *port)
609 for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) {
610 fd = open_socket_in(SOCK_STREAM,
621 fd = open_socket_in(SOCK_STREAM,
628 DEBUG(0, ("Failed to create socket on port %u!\n", *port));
632 DEBUG(10, ("Opened tcpip socket fd %d for port %u\n", fd, *port));
637 uint16_t setup_dcerpc_ncacn_tcpip_socket(struct tevent_context *ev_ctx,
638 struct messaging_context *msg_ctx,
639 const struct sockaddr_storage *ifss,
642 struct dcerpc_ncacn_listen_state *state;
643 struct tevent_fd *fde;
646 state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
648 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Out of memory\n"));
653 state->ep.port = port;
654 state->disconnect_fn = NULL;
656 state->fd = create_tcpip_socket(ifss, &state->ep.port);
657 if (state->fd == -1) {
661 state->ev_ctx = ev_ctx;
662 state->msg_ctx = msg_ctx;
664 /* ready to listen */
665 set_socket_options(state->fd, "SO_KEEPALIVE");
666 set_socket_options(state->fd, lp_socket_options());
668 /* Set server socket to non-blocking for the accept. */
669 set_blocking(state->fd, false);
671 rc = listen(state->fd, SMBD_LISTEN_BACKLOG);
673 DEBUG(0,("setup_tcpip_socket: listen - %s\n", strerror(errno)));
677 DEBUG(10, ("setup_tcpip_socket: openened socket fd %d for port %u\n",
678 state->fd, state->ep.port));
680 fde = tevent_add_fd(state->ev_ctx,
684 dcerpc_ncacn_tcpip_listener,
687 DEBUG(0, ("setup_tcpip_socket: Failed to add event handler!\n"));
691 tevent_fd_set_auto_close(fde);
693 return state->ep.port;
695 if (state->fd != -1) {
703 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
704 struct tevent_fd *fde,
708 struct dcerpc_ncacn_listen_state *state =
709 talloc_get_type_abort(private_data,
710 struct dcerpc_ncacn_listen_state);
711 struct tsocket_address *cli_addr = NULL;
712 struct tsocket_address *srv_addr = NULL;
713 struct sockaddr_storage addr;
714 socklen_t in_addrlen = sizeof(addr);
718 s = accept(state->fd, (struct sockaddr *)(void *) &addr, &in_addrlen);
720 if (errno != EINTR) {
721 DEBUG(0,("tcpip_listener accept: %s\n",
726 smb_set_close_on_exec(s);
728 rc = tsocket_address_bsd_from_sockaddr(state,
729 (struct sockaddr *)(void *) &addr,
737 rc = getsockname(s, (struct sockaddr *)(void *) &addr, &in_addrlen);
743 rc = tsocket_address_bsd_from_sockaddr(state,
744 (struct sockaddr *)(void *) &addr,
752 DEBUG(6, ("tcpip_listener: Accepted socket %d\n", s));
754 dcerpc_ncacn_accept(state->ev_ctx,
764 /********************************************************************
765 * Start listening on the ncalrpc socket
766 ********************************************************************/
768 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
769 struct tevent_fd *fde,
773 int create_dcerpc_ncalrpc_socket(const char *name)
781 if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
782 DEBUG(0, ("Failed to create ncalrpc directory %s - %s\n",
783 lp_ncalrpc_dir(), strerror(errno)));
787 fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
789 DEBUG(0, ("Failed to create ncalrpc socket! [%s/%s]\n",
790 lp_ncalrpc_dir(), name));
794 DEBUG(10, ("Opened ncalrpc socket fd %d for %s\n", fd, name));
799 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
800 struct messaging_context *msg_ctx,
802 dcerpc_ncacn_disconnect_fn fn)
804 struct dcerpc_ncacn_listen_state *state;
805 struct tevent_fd *fde;
808 state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
810 DEBUG(0, ("Out of memory\n"));
815 state->disconnect_fn = fn;
821 state->ep.name = talloc_strdup(state, name);
822 if (state->ep.name == NULL) {
823 DEBUG(0, ("Out of memory\n"));
828 state->fd = create_dcerpc_ncalrpc_socket(name);
829 if (state->fd == -1) {
833 rc = listen(state->fd, 5);
835 DEBUG(0, ("Failed to listen on ncalrpc socket %s: %s\n",
836 name, strerror(errno)));
840 state->ev_ctx = ev_ctx;
841 state->msg_ctx = msg_ctx;
843 /* Set server socket to non-blocking for the accept. */
844 set_blocking(state->fd, false);
846 fde = tevent_add_fd(state->ev_ctx,
850 dcerpc_ncalrpc_listener,
853 DEBUG(0, ("Failed to add event handler for ncalrpc!\n"));
857 tevent_fd_set_auto_close(fde);
861 if (state->fd != -1) {
869 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
870 struct tevent_fd *fde,
874 struct dcerpc_ncacn_listen_state *state =
875 talloc_get_type_abort(private_data,
876 struct dcerpc_ncacn_listen_state);
877 struct tsocket_address *cli_addr = NULL, *srv_addr = NULL;
878 struct sockaddr_un sunaddr;
879 struct sockaddr *addr = (struct sockaddr *)(void *)&sunaddr;
880 socklen_t len = sizeof(sunaddr);
881 struct sockaddr_un sunaddr_server;
882 struct sockaddr *addr_server = (struct sockaddr *)(void *)&sunaddr_server;
883 socklen_t len_server = sizeof(sunaddr_server);
887 ZERO_STRUCT(sunaddr);
888 ZERO_STRUCT(sunaddr_server);
890 sd = accept(state->fd, addr, &len);
892 if (errno != EINTR) {
893 DEBUG(0, ("ncalrpc accept() failed: %s\n", strerror(errno)));
897 smb_set_close_on_exec(sd);
899 rc = tsocket_address_bsd_from_sockaddr(state,
907 rc = getsockname(sd, addr_server, &len_server);
913 rc = tsocket_address_bsd_from_sockaddr(state,
922 DEBUG(10, ("Accepted ncalrpc socket %s (fd: %d)\n",
923 sunaddr.sun_path, sd));
925 dcerpc_ncacn_accept(state->ev_ctx,
929 cli_addr, srv_addr, sd,
930 state->disconnect_fn);
933 struct dcerpc_ncacn_conn {
934 enum dcerpc_transport_t transport;
938 struct pipes_struct *p;
939 dcerpc_ncacn_disconnect_fn disconnect_fn;
941 struct tevent_context *ev_ctx;
942 struct messaging_context *msg_ctx;
944 struct tstream_context *tstream;
945 struct tevent_queue *send_queue;
947 struct tsocket_address *remote_client_addr;
948 char *remote_client_name;
949 struct tsocket_address *local_server_addr;
950 char *local_server_name;
951 struct auth_session_info *session_info;
957 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
958 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
960 void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
961 struct messaging_context *msg_ctx,
962 enum dcerpc_transport_t transport,
964 struct tsocket_address *cli_addr,
965 struct tsocket_address *srv_addr,
967 dcerpc_ncacn_disconnect_fn fn) {
968 struct dcerpc_ncacn_conn *ncacn_conn;
969 struct tevent_req *subreq;
977 DEBUG(10, ("dcerpc_ncacn_accept\n"));
979 ncacn_conn = talloc_zero(ev_ctx, struct dcerpc_ncacn_conn);
980 if (ncacn_conn == NULL) {
981 DEBUG(0, ("Out of memory!\n"));
986 ncacn_conn->transport = transport;
987 ncacn_conn->ev_ctx = ev_ctx;
988 ncacn_conn->msg_ctx = msg_ctx;
989 ncacn_conn->sock = s;
990 ncacn_conn->disconnect_fn = fn;
992 ncacn_conn->remote_client_addr = talloc_move(ncacn_conn, &cli_addr);
993 if (tsocket_address_is_inet(ncacn_conn->remote_client_addr, "ip")) {
994 ncacn_conn->remote_client_name =
995 tsocket_address_inet_addr_string(ncacn_conn->remote_client_addr,
998 ncacn_conn->remote_client_name =
999 tsocket_address_unix_path(ncacn_conn->remote_client_addr,
1002 if (ncacn_conn->remote_client_name == NULL) {
1003 DEBUG(0, ("Out of memory obtaining remote socket address as a string!\n"));
1004 talloc_free(ncacn_conn);
1009 if (srv_addr != NULL) {
1010 ncacn_conn->local_server_addr = talloc_move(ncacn_conn, &srv_addr);
1012 if (tsocket_address_is_inet(ncacn_conn->local_server_addr, "ip")) {
1013 ncacn_conn->local_server_name =
1014 tsocket_address_inet_addr_string(ncacn_conn->local_server_addr,
1017 ncacn_conn->local_server_name =
1018 tsocket_address_unix_path(ncacn_conn->local_server_addr,
1021 if (ncacn_conn->local_server_name == NULL) {
1022 DEBUG(0, ("Out of memory obtaining local socket address as a string!\n"));
1023 talloc_free(ncacn_conn);
1029 switch (transport) {
1031 pipe_name = tsocket_address_string(ncacn_conn->remote_client_addr,
1033 if (pipe_name == NULL) {
1035 talloc_free(ncacn_conn);
1041 rc = getpeereid(s, &uid, &gid);
1043 DEBUG(2, ("Failed to get ncalrpc connecting "
1044 "uid - %s!\n", strerror(errno)));
1046 if (uid == sec_initial_uid()) {
1047 TALLOC_FREE(ncacn_conn->remote_client_addr);
1049 rc = tsocket_address_unix_from_path(ncacn_conn,
1050 AS_SYSTEM_MAGIC_PATH_TOKEN,
1051 &ncacn_conn->remote_client_addr);
1053 DEBUG(0, ("Out of memory building magic ncalrpc_as_system path!\n"));
1054 talloc_free(ncacn_conn);
1059 TALLOC_FREE(ncacn_conn->remote_client_name);
1060 ncacn_conn->remote_client_name
1061 = tsocket_address_unix_path(ncacn_conn->remote_client_addr,
1063 if (ncacn_conn->remote_client_name == NULL) {
1064 DEBUG(0, ("Out of memory getting magic ncalrpc_as_system string!\n"));
1065 talloc_free(ncacn_conn);
1073 pipe_name = talloc_strdup(ncacn_conn,
1075 if (pipe_name == NULL) {
1077 talloc_free(ncacn_conn);
1082 DEBUG(0, ("unknown dcerpc transport: %u!\n",
1084 talloc_free(ncacn_conn);
1089 rc = set_blocking(s, false);
1091 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1092 talloc_free(ncacn_conn);
1098 * As soon as we have tstream_bsd_existing_socket set up it will
1099 * take care of closing the socket.
1101 rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream);
1103 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1104 talloc_free(ncacn_conn);
1109 if (ncacn_conn->session_info == NULL) {
1110 status = make_session_info_anonymous(ncacn_conn,
1111 &ncacn_conn->session_info);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 DEBUG(2, ("Failed to create "
1114 "make_session_info_anonymous - %s\n",
1115 nt_errstr(status)));
1116 talloc_free(ncacn_conn);
1121 rc = make_server_pipes_struct(ncacn_conn,
1122 ncacn_conn->msg_ctx,
1124 ncacn_conn->transport,
1125 ncacn_conn->remote_client_addr,
1126 ncacn_conn->local_server_addr,
1127 ncacn_conn->session_info,
1131 DEBUG(2, ("Failed to create pipe struct - %s",
1132 strerror(sys_errno)));
1133 talloc_free(ncacn_conn);
1137 ncacn_conn->send_queue = tevent_queue_create(ncacn_conn,
1138 "dcerpc send queue");
1139 if (ncacn_conn->send_queue == NULL) {
1140 DEBUG(0, ("Out of memory building dcerpc send queue!\n"));
1141 talloc_free(ncacn_conn);
1145 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1147 ncacn_conn->tstream);
1148 if (subreq == NULL) {
1149 DEBUG(2, ("Failed to send ncacn packet\n"));
1150 talloc_free(ncacn_conn);
1154 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1156 DEBUG(10, ("dcerpc_ncacn_accept done\n"));
1161 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq)
1163 struct dcerpc_ncacn_conn *ncacn_conn =
1164 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1166 struct _output_data *out = &ncacn_conn->p->out_data;
1167 DATA_BLOB recv_buffer = data_blob_null;
1168 struct ncacn_packet *pkt;
1173 status = dcerpc_read_ncacn_packet_recv(subreq, ncacn_conn, &pkt, &recv_buffer);
1174 TALLOC_FREE(subreq);
1175 if (!NT_STATUS_IS_OK(status)) {
1176 if (ncacn_conn->disconnect_fn != NULL) {
1177 ok = ncacn_conn->disconnect_fn(ncacn_conn->p);
1179 DEBUG(3, ("Failed to call disconnect function\n"));
1185 /* dcerpc_read_ncacn_packet_recv() returns a full PDU */
1186 ncacn_conn->p->in_data.pdu_needed_len = 0;
1187 ncacn_conn->p->in_data.pdu = recv_buffer;
1188 if (dcerpc_get_endian_flag(&recv_buffer) & DCERPC_DREP_LE) {
1189 ncacn_conn->p->endian = RPC_LITTLE_ENDIAN;
1191 ncacn_conn->p->endian = RPC_BIG_ENDIAN;
1193 DEBUG(10, ("PDU is in %s Endian format!\n",
1194 ncacn_conn->p->endian ? "Big" : "Little"));
1195 process_complete_pdu(ncacn_conn->p, pkt);
1197 /* reset pipe state and free PDU */
1198 ncacn_conn->p->in_data.pdu.length = 0;
1199 talloc_free(recv_buffer.data);
1203 * This is needed because of the way DCERPC binds work in the RPC
1206 to_send = out->frag.length - out->current_pdu_sent;
1209 DEBUG(10, ("Current_pdu_len = %u, "
1210 "current_pdu_sent = %u "
1211 "Returning %u bytes\n",
1212 (unsigned int)out->frag.length,
1213 (unsigned int)out->current_pdu_sent,
1214 (unsigned int)to_send));
1216 ncacn_conn->iov = talloc_zero(ncacn_conn, struct iovec);
1217 if (ncacn_conn->iov == NULL) {
1218 status = NT_STATUS_NO_MEMORY;
1219 DEBUG(3, ("Out of memory!\n"));
1222 ncacn_conn->count = 1;
1224 ncacn_conn->iov[0].iov_base = out->frag.data
1225 + out->current_pdu_sent;
1226 ncacn_conn->iov[0].iov_len = to_send;
1228 out->current_pdu_sent += to_send;
1232 * This condition is false for bind packets, or when we haven't yet got
1233 * a full request, and need to wait for more data from the client
1235 while (out->data_sent_length < out->rdata.length) {
1236 ok = create_next_pdu(ncacn_conn->p);
1238 DEBUG(3, ("Failed to create next PDU!\n"));
1239 status = NT_STATUS_UNEXPECTED_IO_ERROR;
1243 ncacn_conn->iov = talloc_realloc(ncacn_conn,
1246 ncacn_conn->count + 1);
1247 if (ncacn_conn->iov == NULL) {
1248 DEBUG(3, ("Out of memory!\n"));
1249 status = NT_STATUS_NO_MEMORY;
1253 ncacn_conn->iov[ncacn_conn->count].iov_base = out->frag.data;
1254 ncacn_conn->iov[ncacn_conn->count].iov_len = out->frag.length;
1256 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
1257 (unsigned int) ncacn_conn->count,
1258 (unsigned int) ncacn_conn->iov[ncacn_conn->count].iov_len));
1259 dump_data(11, (const uint8_t *) ncacn_conn->iov[ncacn_conn->count].iov_base,
1260 ncacn_conn->iov[ncacn_conn->count].iov_len);
1261 ncacn_conn->count++;
1265 * We still don't have a complete request, go back and wait for more
1268 if (ncacn_conn->count == 0) {
1269 /* Wait for the next packet */
1270 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1272 ncacn_conn->tstream);
1273 if (subreq == NULL) {
1274 DEBUG(2, ("Failed to start receving packets\n"));
1275 status = NT_STATUS_NO_MEMORY;
1278 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1282 DEBUG(10, ("Sending a total of %u bytes\n",
1283 (unsigned int)ncacn_conn->p->out_data.data_sent_length));
1285 subreq = tstream_writev_queue_send(ncacn_conn,
1287 ncacn_conn->tstream,
1288 ncacn_conn->send_queue,
1291 if (subreq == NULL) {
1292 DEBUG(2, ("Failed to send packet\n"));
1293 status = NT_STATUS_NO_MEMORY;
1297 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_done, ncacn_conn);
1301 DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1302 ncacn_conn->remote_client_name, nt_errstr(status)));
1304 /* Terminate client connection */
1305 talloc_free(ncacn_conn);
1309 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq)
1311 struct dcerpc_ncacn_conn *ncacn_conn =
1312 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1313 NTSTATUS status = NT_STATUS_OK;
1317 rc = tstream_writev_queue_recv(subreq, &sys_errno);
1318 TALLOC_FREE(subreq);
1320 DEBUG(2, ("Writev failed!\n"));
1321 status = map_nt_error_from_unix(sys_errno);
1325 if (ncacn_conn->p->fault_state != 0) {
1326 DEBUG(2, ("Disconnect after fault\n"));
1331 /* clear out any data that may have been left around */
1332 ncacn_conn->count = 0;
1333 TALLOC_FREE(ncacn_conn->iov);
1334 data_blob_free(&ncacn_conn->p->in_data.data);
1335 data_blob_free(&ncacn_conn->p->out_data.frag);
1336 data_blob_free(&ncacn_conn->p->out_data.rdata);
1338 talloc_free_children(ncacn_conn->p->mem_ctx);
1340 /* Wait for the next packet */
1341 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1343 ncacn_conn->tstream);
1344 if (subreq == NULL) {
1345 DEBUG(2, ("Failed to start receving packets\n"));
1346 status = NT_STATUS_NO_MEMORY;
1350 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1354 DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1355 ncacn_conn->remote_client_name, nt_errstr(status)));
1357 /* Terminate client connection */
1358 talloc_free(ncacn_conn);
1362 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */