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"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "librpc/gen_ndr/auth.h"
28 #include "lib/tsocket/tsocket.h"
29 #include "libcli/named_pipe_auth/npa_tstream.h"
30 #include "../auth/auth_sam_reply.h"
32 #include "rpc_server/rpc_ncacn_np.h"
33 #include "rpc_server/srv_pipe_hnd.h"
34 #include "rpc_server/srv_pipe.h"
36 #define SERVER_TCP_LOW_PORT 1024
37 #define SERVER_TCP_HIGH_PORT 1300
39 static NTSTATUS auth_anonymous_session_info(TALLOC_CTX *mem_ctx,
40 struct auth_session_info **session_info)
44 status = make_session_info_guest(mem_ctx, session_info);
45 if (!NT_STATUS_IS_OK(status)) {
52 /* Creates a pipes_struct and initializes it with the information
53 * sent from the client */
54 static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
55 struct messaging_context *msg_ctx,
56 const char *pipe_name,
57 enum dcerpc_transport_t transport,
58 bool ncalrpc_as_system,
59 const struct tsocket_address *local_address,
60 const struct tsocket_address *remote_address,
61 struct auth_session_info *session_info,
62 struct pipes_struct **_p,
65 struct pipes_struct *p;
69 ret = make_base_pipes_struct(mem_ctx, msg_ctx, pipe_name,
70 transport, RPC_LITTLE_ENDIAN,
72 remote_address, local_address, &p);
78 if (session_info->unix_token && session_info->unix_info && session_info->security_token) {
79 /* Don't call create_local_token(), we already have the full details here */
80 p->session_info = talloc_steal(p, session_info);
83 struct auth_user_info_dc *auth_user_info_dc;
84 struct auth_serversupplied_info *server_info;
85 struct netr_SamInfo3 *info3;
87 /* Fake up an auth_user_info_dc for now, to make an info3, to make the session_info structure */
88 auth_user_info_dc = talloc_zero(p, struct auth_user_info_dc);
89 if (!auth_user_info_dc) {
95 auth_user_info_dc->num_sids = session_info->security_token->num_sids;
96 auth_user_info_dc->sids = session_info->security_token->sids;
97 auth_user_info_dc->info = session_info->info;
98 auth_user_info_dc->user_session_key = session_info->session_key;
100 /* This creates the input structure that make_server_info_info3 is looking for */
101 status = auth_convert_user_info_dc_saminfo3(p, auth_user_info_dc,
104 if (!NT_STATUS_IS_OK(status)) {
105 DEBUG(1, ("Failed to convert auth_user_info_dc into netr_SamInfo3\n"));
111 status = make_server_info_info3(p,
112 info3->base.account_name.string,
113 info3->base.domain.string,
114 &server_info, info3);
115 if (!NT_STATUS_IS_OK(status)) {
116 DEBUG(1, ("Failed to init server info\n"));
123 * Some internal functions need a local token to determine access to
126 status = create_local_token(p, server_info, &session_info->session_key, info3->base.account_name.string,
128 talloc_free(server_info);
129 if (!NT_STATUS_IS_OK(status)) {
130 DEBUG(1, ("Failed to init local auth token\n"));
141 /* Start listening on the appropriate unix socket and setup all is needed to
142 * dispatch requests to the pipes rpc implementation */
144 struct dcerpc_ncacn_listen_state {
145 struct ndr_syntax_id syntax_id;
153 struct tevent_context *ev_ctx;
154 struct messaging_context *msg_ctx;
155 dcerpc_ncacn_disconnect_fn disconnect_fn;
158 static void named_pipe_listener(struct tevent_context *ev,
159 struct tevent_fd *fde,
163 int create_named_pipe_socket(const char *pipe_name)
169 * As lp_ncalrpc_dir() should have 0755, but
170 * lp_ncalrpc_dir()/np should have 0700, we need to
171 * create lp_ncalrpc_dir() first.
173 if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
174 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
175 lp_ncalrpc_dir(), strerror(errno)));
179 np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
181 DEBUG(0, ("Out of memory\n"));
185 if (!directory_create_or_exist(np_dir, geteuid(), 0700)) {
186 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
187 np_dir, strerror(errno)));
191 fd = create_pipe_sock(np_dir, pipe_name, 0700);
193 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
198 DEBUG(10, ("Openened pipe socket fd %d for %s\n", fd, pipe_name));
205 bool setup_named_pipe_socket(const char *pipe_name,
206 struct tevent_context *ev_ctx,
207 struct messaging_context *msg_ctx)
209 struct dcerpc_ncacn_listen_state *state;
210 struct tevent_fd *fde;
212 state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
214 DEBUG(0, ("Out of memory\n"));
217 state->ep.name = talloc_strdup(state, pipe_name);
218 if (state->ep.name == NULL) {
219 DEBUG(0, ("Out of memory\n"));
222 state->fd = create_named_pipe_socket(pipe_name);
223 if (state->fd == -1) {
227 state->ev_ctx = ev_ctx;
228 state->msg_ctx = msg_ctx;
230 DEBUG(10, ("Openened pipe socket fd %d for %s\n",
231 state->fd, pipe_name));
233 fde = tevent_add_fd(ev_ctx,
234 state, state->fd, TEVENT_FD_READ,
235 named_pipe_listener, state);
237 DEBUG(0, ("Failed to add event handler!\n"));
241 tevent_fd_set_auto_close(fde);
245 if (state->fd != -1) {
252 static void named_pipe_listener(struct tevent_context *ev,
253 struct tevent_fd *fde,
257 struct dcerpc_ncacn_listen_state *state =
258 talloc_get_type_abort(private_data,
259 struct dcerpc_ncacn_listen_state);
260 struct sockaddr_un sunaddr;
264 /* TODO: should we have a limit to the number of clients ? */
266 len = sizeof(sunaddr);
268 sd = accept(state->fd,
269 (struct sockaddr *)(void *)&sunaddr, &len);
272 if (errno != EINTR) {
273 DEBUG(6, ("Failed to get a valid socket [%s]\n",
279 DEBUG(6, ("Accepted socket %d\n", sd));
281 named_pipe_accept_function(state->ev_ctx,
288 /* This is the core of the rpc server.
289 * Accepts connections from clients and process requests using the appropriate
290 * dispatcher table. */
292 struct named_pipe_client {
293 const char *pipe_name;
295 struct tevent_context *ev;
296 struct messaging_context *msg_ctx;
299 uint16_t device_state;
300 uint64_t allocation_size;
302 struct tstream_context *tstream;
304 struct tsocket_address *client;
306 struct tsocket_address *server;
309 struct auth_session_info *session_info;
311 struct pipes_struct *p;
313 struct tevent_queue *write_queue;
318 named_pipe_termination_fn *term_fn;
322 static int named_pipe_destructor(struct named_pipe_client *npc)
325 npc->term_fn(npc->private_data);
330 static void named_pipe_accept_done(struct tevent_req *subreq);
332 void named_pipe_accept_function(struct tevent_context *ev_ctx,
333 struct messaging_context *msg_ctx,
334 const char *pipe_name, int fd,
335 named_pipe_termination_fn *term_fn,
338 struct named_pipe_client *npc;
339 struct tstream_context *plain;
340 struct tevent_req *subreq;
343 npc = talloc_zero(ev_ctx, struct named_pipe_client);
345 DEBUG(0, ("Out of memory!\n"));
350 npc->pipe_name = talloc_strdup(npc, pipe_name);
351 if (npc->pipe_name == NULL) {
352 DEBUG(0, ("Out of memory!\n"));
358 npc->msg_ctx = msg_ctx;
359 npc->term_fn = term_fn;
360 npc->private_data = private_data;
362 talloc_set_destructor(npc, named_pipe_destructor);
364 /* make sure socket is in NON blocking state */
365 ret = set_blocking(fd, false);
367 DEBUG(2, ("Failed to make socket non-blocking\n"));
373 ret = tstream_bsd_existing_socket(npc, fd, &plain);
375 DEBUG(2, ("Failed to create tstream socket\n"));
381 npc->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
382 npc->device_state = 0xff | 0x0400 | 0x0100;
383 npc->allocation_size = 4096;
385 subreq = tstream_npa_accept_existing_send(npc, npc->ev, plain,
388 npc->allocation_size);
390 DEBUG(2, ("Failed to start async accept procedure\n"));
395 tevent_req_set_callback(subreq, named_pipe_accept_done, npc);
398 static void named_pipe_packet_process(struct tevent_req *subreq);
399 static void named_pipe_packet_done(struct tevent_req *subreq);
401 static void named_pipe_accept_done(struct tevent_req *subreq)
403 struct auth_session_info_transport *session_info_transport;
404 struct named_pipe_client *npc =
405 tevent_req_callback_data(subreq, struct named_pipe_client);
409 ret = tstream_npa_accept_existing_recv(subreq, &error, npc,
415 &session_info_transport);
417 npc->session_info = talloc_move(npc, &session_info_transport->session_info);
421 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
427 ret = make_server_pipes_struct(npc,
429 npc->pipe_name, NCACN_NP,
430 false, npc->server, npc->client, npc->session_info,
433 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
438 npc->write_queue = tevent_queue_create(npc, "np_server_write_queue");
439 if (!npc->write_queue) {
440 DEBUG(2, ("Failed to set up write queue!\n"));
444 /* And now start receiving and processing packets */
445 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
447 DEBUG(2, ("Failed to start receving packets\n"));
450 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
454 DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
456 /* terminate client connection */
461 static void named_pipe_packet_process(struct tevent_req *subreq)
463 struct named_pipe_client *npc =
464 tevent_req_callback_data(subreq, struct named_pipe_client);
465 struct _output_data *out = &npc->p->out_data;
466 DATA_BLOB recv_buffer = data_blob_null;
467 struct ncacn_packet *pkt;
476 status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer);
478 if (!NT_STATUS_IS_OK(status)) {
482 data_left = recv_buffer.length;
483 data = (char *)recv_buffer.data;
487 data_used = process_incoming_data(npc->p, data, data_left);
489 DEBUG(3, ("Failed to process dceprc request!\n"));
490 status = NT_STATUS_UNEXPECTED_IO_ERROR;
494 data_left -= data_used;
498 /* Do not leak this buffer, npc is a long lived context */
499 talloc_free(recv_buffer.data);
502 /* this is needed because of the way DCERPC Binds work in
503 * the RPC marshalling code */
504 to_send = out->frag.length - out->current_pdu_sent;
507 npc->iov = talloc_zero(npc, struct iovec);
509 status = NT_STATUS_NO_MEMORY;
514 npc->iov[0].iov_base = out->frag.data
515 + out->current_pdu_sent;
516 npc->iov[0].iov_len = to_send;
518 out->current_pdu_sent += to_send;
521 /* this condition is false for bind packets, or when we haven't
522 * yet got a full request, and need to wait for more data from
524 while (out->data_sent_length < out->rdata.length) {
526 ok = create_next_pdu(npc->p);
528 DEBUG(3, ("Failed to create next PDU!\n"));
529 status = NT_STATUS_UNEXPECTED_IO_ERROR;
533 npc->iov = talloc_realloc(npc, npc->iov,
534 struct iovec, npc->count + 1);
536 status = NT_STATUS_NO_MEMORY;
540 npc->iov[npc->count].iov_base = out->frag.data;
541 npc->iov[npc->count].iov_len = out->frag.length;
546 /* we still don't have a complete request, go back and wait for more
548 if (npc->count == 0) {
549 /* Wait for the next packet */
550 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
552 DEBUG(2, ("Failed to start receving packets\n"));
553 status = NT_STATUS_NO_MEMORY;
556 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
560 DEBUG(10, ("Sending %u fragments in a total of %u bytes\n",
561 (unsigned int)npc->count,
562 (unsigned int)npc->p->out_data.data_sent_length));
564 for (i = 0; i < npc->count; i++) {
565 DEBUG(10, ("Sending PDU number: %d, PDU Length: %u\n",
567 (unsigned int)npc->iov[i].iov_len));
568 dump_data(11, (const uint8_t *)npc->iov[i].iov_base,
569 npc->iov[i].iov_len);
571 subreq = tstream_writev_queue_send(npc,
578 DEBUG(2, ("Failed to send packet\n"));
579 status = NT_STATUS_NO_MEMORY;
582 tevent_req_set_callback(subreq, named_pipe_packet_done, npc);
588 DEBUG(2, ("Fatal error(%s). "
589 "Terminating client(%s) connection!\n",
590 nt_errstr(status), npc->client_name));
591 /* terminate client connection */
596 static void named_pipe_packet_done(struct tevent_req *subreq)
598 struct named_pipe_client *npc =
599 tevent_req_callback_data(subreq, struct named_pipe_client);
603 ret = tstream_writev_queue_recv(subreq, &sys_errno);
606 DEBUG(2, ("Writev failed!\n"));
610 if (tevent_queue_length(npc->write_queue) > 0) {
614 /* clear out any data that may have been left around */
616 TALLOC_FREE(npc->iov);
617 data_blob_free(&npc->p->in_data.data);
618 data_blob_free(&npc->p->out_data.frag);
619 data_blob_free(&npc->p->out_data.rdata);
621 talloc_free_children(npc->p->mem_ctx);
623 /* Wait for the next packet */
624 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
626 DEBUG(2, ("Failed to start receving packets\n"));
630 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
634 DEBUG(2, ("Fatal error(%s). "
635 "Terminating client(%s) connection!\n",
636 strerror(sys_errno), npc->client_name));
637 /* terminate client connection */
642 /********************************************************************
643 * Start listening on the tcp/ip socket
644 ********************************************************************/
646 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
647 struct tevent_fd *fde,
651 int create_tcpip_socket(const struct sockaddr_storage *ifss, uint16_t *port)
658 for (i = SERVER_TCP_LOW_PORT; i <= SERVER_TCP_HIGH_PORT; i++) {
659 fd = open_socket_in(SOCK_STREAM,
670 fd = open_socket_in(SOCK_STREAM,
677 DEBUG(0, ("Failed to create socket on port %u!\n", *port));
681 DEBUG(10, ("Opened tcpip socket fd %d for port %u\n", fd, *port));
686 uint16_t setup_dcerpc_ncacn_tcpip_socket(struct tevent_context *ev_ctx,
687 struct messaging_context *msg_ctx,
688 const struct sockaddr_storage *ifss,
691 struct dcerpc_ncacn_listen_state *state;
692 struct tevent_fd *fde;
695 state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
697 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Out of memory\n"));
702 state->ep.port = port;
703 state->disconnect_fn = NULL;
705 state->fd = create_tcpip_socket(ifss, &state->ep.port);
706 if (state->fd == -1) {
710 state->ev_ctx = ev_ctx;
711 state->msg_ctx = msg_ctx;
713 /* ready to listen */
714 set_socket_options(state->fd, "SO_KEEPALIVE");
715 set_socket_options(state->fd, lp_socket_options());
717 /* Set server socket to non-blocking for the accept. */
718 set_blocking(state->fd, false);
720 rc = listen(state->fd, SMBD_LISTEN_BACKLOG);
722 DEBUG(0,("setup_tcpip_socket: listen - %s\n", strerror(errno)));
726 DEBUG(10, ("setup_tcpip_socket: openened socket fd %d for port %u\n",
727 state->fd, state->ep.port));
729 fde = tevent_add_fd(state->ev_ctx,
733 dcerpc_ncacn_tcpip_listener,
736 DEBUG(0, ("setup_tcpip_socket: Failed to add event handler!\n"));
740 tevent_fd_set_auto_close(fde);
742 return state->ep.port;
744 if (state->fd != -1) {
752 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
753 struct tevent_fd *fde,
757 struct dcerpc_ncacn_listen_state *state =
758 talloc_get_type_abort(private_data,
759 struct dcerpc_ncacn_listen_state);
760 struct tsocket_address *cli_addr = NULL;
761 struct tsocket_address *srv_addr = NULL;
762 struct sockaddr_storage addr;
763 socklen_t in_addrlen = sizeof(addr);
767 s = accept(state->fd, (struct sockaddr *)(void *) &addr, &in_addrlen);
769 if (errno != EINTR) {
770 DEBUG(0,("tcpip_listener accept: %s\n",
776 rc = tsocket_address_bsd_from_sockaddr(state,
777 (struct sockaddr *)(void *) &addr,
785 rc = getsockname(s, (struct sockaddr *)(void *) &addr, &in_addrlen);
791 rc = tsocket_address_bsd_from_sockaddr(state,
792 (struct sockaddr *)(void *) &addr,
800 DEBUG(6, ("tcpip_listener: Accepted socket %d\n", s));
802 dcerpc_ncacn_accept(state->ev_ctx,
812 /********************************************************************
813 * Start listening on the ncalrpc socket
814 ********************************************************************/
816 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
817 struct tevent_fd *fde,
821 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
822 struct messaging_context *msg_ctx,
824 dcerpc_ncacn_disconnect_fn fn)
826 struct dcerpc_ncacn_listen_state *state;
827 struct tevent_fd *fde;
829 state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
831 DEBUG(0, ("Out of memory\n"));
836 state->disconnect_fn = fn;
841 state->ep.name = talloc_strdup(state, name);
843 if (state->ep.name == NULL) {
844 DEBUG(0, ("Out of memory\n"));
849 if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
850 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
851 lp_ncalrpc_dir(), strerror(errno)));
855 state->fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
856 if (state->fd == -1) {
857 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
858 lp_ncalrpc_dir(), name));
862 DEBUG(10, ("Openened pipe socket fd %d for %s\n", state->fd, name));
864 state->ev_ctx = ev_ctx;
865 state->msg_ctx = msg_ctx;
867 /* Set server socket to non-blocking for the accept. */
868 set_blocking(state->fd, false);
870 fde = tevent_add_fd(state->ev_ctx,
874 dcerpc_ncalrpc_listener,
877 DEBUG(0, ("Failed to add event handler for ncalrpc!\n"));
881 tevent_fd_set_auto_close(fde);
885 if (state->fd != -1) {
893 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
894 struct tevent_fd *fde,
898 struct dcerpc_ncacn_listen_state *state =
899 talloc_get_type_abort(private_data,
900 struct dcerpc_ncacn_listen_state);
901 struct tsocket_address *cli_addr = NULL;
902 struct sockaddr_un sunaddr;
903 struct sockaddr *addr = (struct sockaddr *)(void *)&sunaddr;
904 socklen_t len = sizeof(sunaddr);
908 ZERO_STRUCT(sunaddr);
910 sd = accept(state->fd, addr, &len);
912 if (errno != EINTR) {
913 DEBUG(0, ("ncalrpc accept() failed: %s\n", strerror(errno)));
918 rc = tsocket_address_bsd_from_sockaddr(state,
926 DEBUG(10, ("Accepted ncalrpc socket %d\n", sd));
928 dcerpc_ncacn_accept(state->ev_ctx,
933 state->disconnect_fn);
936 struct dcerpc_ncacn_conn {
937 enum dcerpc_transport_t transport;
941 struct pipes_struct *p;
942 dcerpc_ncacn_disconnect_fn disconnect_fn;
944 struct tevent_context *ev_ctx;
945 struct messaging_context *msg_ctx;
947 struct tstream_context *tstream;
948 struct tevent_queue *send_queue;
950 struct tsocket_address *client;
952 struct tsocket_address *server;
954 struct auth_session_info *session_info;
960 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
961 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
963 void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
964 struct messaging_context *msg_ctx,
965 enum dcerpc_transport_t transport,
967 struct tsocket_address *cli_addr,
968 struct tsocket_address *srv_addr,
970 dcerpc_ncacn_disconnect_fn fn) {
971 struct dcerpc_ncacn_conn *ncacn_conn;
972 struct tevent_req *subreq;
973 bool system_user = false;
980 DEBUG(10, ("dcerpc_ncacn_accept\n"));
982 ncacn_conn = talloc_zero(ev_ctx, struct dcerpc_ncacn_conn);
983 if (ncacn_conn == NULL) {
984 DEBUG(0, ("Out of memory!\n"));
989 ncacn_conn->transport = transport;
990 ncacn_conn->ev_ctx = ev_ctx;
991 ncacn_conn->msg_ctx = msg_ctx;
992 ncacn_conn->sock = s;
993 ncacn_conn->disconnect_fn = fn;
995 ncacn_conn->client = talloc_move(ncacn_conn, &cli_addr);
996 if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
997 ncacn_conn->client_name =
998 tsocket_address_inet_addr_string(ncacn_conn->client,
1001 ncacn_conn->client_name =
1002 tsocket_address_unix_path(ncacn_conn->client,
1005 if (ncacn_conn->client_name == NULL) {
1006 DEBUG(0, ("Out of memory!\n"));
1007 talloc_free(ncacn_conn);
1012 if (srv_addr != NULL) {
1013 ncacn_conn->server = talloc_move(ncacn_conn, &srv_addr);
1015 ncacn_conn->server_name =
1016 tsocket_address_inet_addr_string(ncacn_conn->server,
1018 if (ncacn_conn->server_name == NULL) {
1019 DEBUG(0, ("Out of memory!\n"));
1020 talloc_free(ncacn_conn);
1026 switch (transport) {
1028 pipe_name = tsocket_address_string(ncacn_conn->client,
1030 if (pipe_name == NULL) {
1032 talloc_free(ncacn_conn);
1038 rc = sys_getpeereid(s, &uid);
1040 DEBUG(2, ("Failed to get ncalrpc connecting uid!"));
1042 if (uid == sec_initial_uid()) {
1047 pipe_name = talloc_strdup(ncacn_conn,
1049 if (pipe_name == NULL) {
1051 talloc_free(ncacn_conn);
1056 DEBUG(0, ("unknown dcerpc transport: %u!\n",
1058 talloc_free(ncacn_conn);
1063 rc = set_blocking(s, false);
1065 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1066 talloc_free(ncacn_conn);
1072 * As soon as we have tstream_bsd_existing_socket set up it will
1073 * take care of closing the socket.
1075 rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream);
1077 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1078 talloc_free(ncacn_conn);
1083 if (ncacn_conn->session_info == NULL) {
1084 status = auth_anonymous_session_info(ncacn_conn,
1085 &ncacn_conn->session_info);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 DEBUG(2, ("Failed to create "
1088 "auth_anonymous_session_info - %s\n",
1089 nt_errstr(status)));
1090 talloc_free(ncacn_conn);
1095 rc = make_server_pipes_struct(ncacn_conn,
1096 ncacn_conn->msg_ctx,
1098 ncacn_conn->transport,
1102 ncacn_conn->session_info,
1106 DEBUG(2, ("Failed to create pipe struct - %s",
1107 strerror(sys_errno)));
1108 talloc_free(ncacn_conn);
1112 ncacn_conn->send_queue = tevent_queue_create(ncacn_conn,
1113 "dcerpc send queue");
1114 if (ncacn_conn->send_queue == NULL) {
1115 DEBUG(0, ("Out of memory!\n"));
1116 talloc_free(ncacn_conn);
1120 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1122 ncacn_conn->tstream);
1123 if (subreq == NULL) {
1124 DEBUG(2, ("Failed to send ncacn packet\n"));
1125 talloc_free(ncacn_conn);
1129 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1131 DEBUG(10, ("dcerpc_ncacn_accept done\n"));
1136 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq)
1138 struct dcerpc_ncacn_conn *ncacn_conn =
1139 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1141 struct _output_data *out = &ncacn_conn->p->out_data;
1142 DATA_BLOB recv_buffer = data_blob_null;
1143 struct ncacn_packet *pkt;
1151 status = dcerpc_read_ncacn_packet_recv(subreq, ncacn_conn, &pkt, &recv_buffer);
1152 TALLOC_FREE(subreq);
1153 if (!NT_STATUS_IS_OK(status)) {
1154 if (ncacn_conn->disconnect_fn != NULL) {
1155 ok = ncacn_conn->disconnect_fn(ncacn_conn->p);
1157 DEBUG(3, ("Failed to call disconnect function\n"));
1163 data_left = recv_buffer.length;
1164 data = (char *) recv_buffer.data;
1167 data_used = process_incoming_data(ncacn_conn->p, data, data_left);
1168 if (data_used < 0) {
1169 DEBUG(3, ("Failed to process dcerpc request!\n"));
1170 status = NT_STATUS_UNEXPECTED_IO_ERROR;
1174 data_left -= data_used;
1178 /* Do not leak this buffer */
1179 talloc_free(recv_buffer.data);
1183 * This is needed because of the way DCERPC binds work in the RPC
1186 to_send = out->frag.length - out->current_pdu_sent;
1189 DEBUG(10, ("Current_pdu_len = %u, "
1190 "current_pdu_sent = %u "
1191 "Returning %u bytes\n",
1192 (unsigned int)out->frag.length,
1193 (unsigned int)out->current_pdu_sent,
1194 (unsigned int)to_send));
1196 ncacn_conn->iov = talloc_zero(ncacn_conn, struct iovec);
1197 if (ncacn_conn->iov == NULL) {
1198 status = NT_STATUS_NO_MEMORY;
1199 DEBUG(3, ("Out of memory!\n"));
1202 ncacn_conn->count = 1;
1204 ncacn_conn->iov[0].iov_base = out->frag.data
1205 + out->current_pdu_sent;
1206 ncacn_conn->iov[0].iov_len = to_send;
1208 out->current_pdu_sent += to_send;
1212 * This condition is false for bind packets, or when we haven't yet got
1213 * a full request, and need to wait for more data from the client
1215 while (out->data_sent_length < out->rdata.length) {
1216 ok = create_next_pdu(ncacn_conn->p);
1218 DEBUG(3, ("Failed to create next PDU!\n"));
1219 status = NT_STATUS_UNEXPECTED_IO_ERROR;
1223 ncacn_conn->iov = talloc_realloc(ncacn_conn,
1226 ncacn_conn->count + 1);
1227 if (ncacn_conn->iov == NULL) {
1228 DEBUG(3, ("Out of memory!\n"));
1229 status = NT_STATUS_NO_MEMORY;
1233 ncacn_conn->iov[ncacn_conn->count].iov_base = out->frag.data;
1234 ncacn_conn->iov[ncacn_conn->count].iov_len = out->frag.length;
1236 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
1237 (unsigned int) ncacn_conn->count,
1238 (unsigned int) ncacn_conn->iov[ncacn_conn->count].iov_len));
1239 dump_data(11, (const uint8_t *) ncacn_conn->iov[ncacn_conn->count].iov_base,
1240 ncacn_conn->iov[ncacn_conn->count].iov_len);
1241 ncacn_conn->count++;
1245 * We still don't have a complete request, go back and wait for more
1248 if (ncacn_conn->count == 0) {
1249 /* Wait for the next packet */
1250 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1252 ncacn_conn->tstream);
1253 if (subreq == NULL) {
1254 DEBUG(2, ("Failed to start receving packets\n"));
1255 status = NT_STATUS_NO_MEMORY;
1258 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1262 DEBUG(10, ("Sending a total of %u bytes\n",
1263 (unsigned int)ncacn_conn->p->out_data.data_sent_length));
1265 subreq = tstream_writev_queue_send(ncacn_conn,
1267 ncacn_conn->tstream,
1268 ncacn_conn->send_queue,
1271 if (subreq == NULL) {
1272 DEBUG(2, ("Failed to send packet\n"));
1273 status = NT_STATUS_NO_MEMORY;
1277 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_done, ncacn_conn);
1281 DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1282 ncacn_conn->client_name, nt_errstr(status)));
1284 /* Terminate client connection */
1285 talloc_free(ncacn_conn);
1289 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq)
1291 struct dcerpc_ncacn_conn *ncacn_conn =
1292 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1293 NTSTATUS status = NT_STATUS_OK;
1297 rc = tstream_writev_queue_recv(subreq, &sys_errno);
1298 TALLOC_FREE(subreq);
1300 DEBUG(2, ("Writev failed!\n"));
1301 status = map_nt_error_from_unix(sys_errno);
1305 /* clear out any data that may have been left around */
1306 ncacn_conn->count = 0;
1307 TALLOC_FREE(ncacn_conn->iov);
1308 data_blob_free(&ncacn_conn->p->in_data.data);
1309 data_blob_free(&ncacn_conn->p->out_data.frag);
1310 data_blob_free(&ncacn_conn->p->out_data.rdata);
1312 talloc_free_children(ncacn_conn->p->mem_ctx);
1314 /* Wait for the next packet */
1315 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1317 ncacn_conn->tstream);
1318 if (subreq == NULL) {
1319 DEBUG(2, ("Failed to start receving packets\n"));
1320 status = NT_STATUS_NO_MEMORY;
1324 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1328 DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1329 ncacn_conn->client_name, nt_errstr(status)));
1331 /* Terminate client connection */
1332 talloc_free(ncacn_conn);
1336 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */