s3-rpc_server: Make named_pipe_packet_process a shared functiion.
[samba.git] / source3 / rpc_server / rpc_server.c
1 /*
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
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "rpc_server/rpc_pipes.h"
24 #include "rpc_server/rpc_server.h"
25 #include "rpc_server/rpc_config.h"
26 #include "rpc_dce.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"
32 #include "auth.h"
33 #include "rpc_server/rpc_ncacn_np.h"
34 #include "rpc_server/srv_pipe_hnd.h"
35 #include "rpc_server/srv_pipe.h"
36
37 #define SERVER_TCP_LOW_PORT  1024
38 #define SERVER_TCP_HIGH_PORT 1300
39
40 static NTSTATUS auth_anonymous_session_info(TALLOC_CTX *mem_ctx,
41                                             struct auth_session_info **session_info)
42 {
43         NTSTATUS status;
44
45         status = make_session_info_guest(mem_ctx, session_info);
46         if (!NT_STATUS_IS_OK(status)) {
47                 return status;
48         }
49
50         return NT_STATUS_OK;
51 }
52
53 /* Creates a pipes_struct and initializes it with the information
54  * sent from the client */
55 int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
56                              struct messaging_context *msg_ctx,
57                              const char *pipe_name,
58                              enum dcerpc_transport_t transport,
59                              bool ncalrpc_as_system,
60                              const struct tsocket_address *local_address,
61                              const struct tsocket_address *remote_address,
62                              struct auth_session_info *session_info,
63                              struct pipes_struct **_p,
64                              int *perrno)
65 {
66         struct pipes_struct *p;
67         int ret;
68
69         ret = make_base_pipes_struct(mem_ctx, msg_ctx, pipe_name,
70                                      transport, RPC_LITTLE_ENDIAN,
71                                      ncalrpc_as_system,
72                                      remote_address, local_address, &p);
73         if (ret) {
74                 *perrno = ret;
75                 return -1;
76         }
77
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);
81
82         } else {
83                 DEBUG(0, ("Supplied session_info in make_server_pipes_struct was incomplete!"));
84                 *perrno = EINVAL;
85                 return -1;
86         }
87
88         *_p = p;
89         return 0;
90 }
91
92 /* Start listening on the appropriate unix socket and setup all is needed to
93  * dispatch requests to the pipes rpc implementation */
94
95 struct dcerpc_ncacn_listen_state {
96         struct ndr_syntax_id syntax_id;
97
98         int fd;
99         union {
100                 char *name;
101                 uint16_t port;
102         } ep;
103
104         struct tevent_context *ev_ctx;
105         struct messaging_context *msg_ctx;
106         dcerpc_ncacn_disconnect_fn disconnect_fn;
107 };
108
109 static void named_pipe_listener(struct tevent_context *ev,
110                                 struct tevent_fd *fde,
111                                 uint16_t flags,
112                                 void *private_data);
113
114 int create_named_pipe_socket(const char *pipe_name)
115 {
116         char *np_dir = NULL;
117         int fd = -1;
118
119         /*
120          * As lp_ncalrpc_dir() should have 0755, but
121          * lp_ncalrpc_dir()/np should have 0700, we need to
122          * create lp_ncalrpc_dir() first.
123          */
124         if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
125                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
126                           lp_ncalrpc_dir(), strerror(errno)));
127                 goto out;
128         }
129
130         np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
131         if (!np_dir) {
132                 DEBUG(0, ("Out of memory\n"));
133                 goto out;
134         }
135
136         if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) {
137                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
138                           np_dir, strerror(errno)));
139                 goto out;
140         }
141
142         fd = create_pipe_sock(np_dir, pipe_name, 0700);
143         if (fd == -1) {
144                 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
145                           np_dir, pipe_name));
146                 goto out;
147         }
148
149         DEBUG(10, ("Openened pipe socket fd %d for %s\n", fd, pipe_name));
150
151 out:
152         talloc_free(np_dir);
153         return fd;
154 }
155
156 bool setup_named_pipe_socket(const char *pipe_name,
157                              struct tevent_context *ev_ctx,
158                              struct messaging_context *msg_ctx)
159 {
160         struct dcerpc_ncacn_listen_state *state;
161         struct tevent_fd *fde;
162         int rc;
163
164         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
165         if (!state) {
166                 DEBUG(0, ("Out of memory\n"));
167                 return false;
168         }
169         state->ep.name = talloc_strdup(state, pipe_name);
170         if (state->ep.name == NULL) {
171                 DEBUG(0, ("Out of memory\n"));
172                 goto out;
173         }
174         state->fd = create_named_pipe_socket(pipe_name);
175         if (state->fd == -1) {
176                 goto out;
177         }
178
179         rc = listen(state->fd, 5);
180         if (rc < 0) {
181                 DEBUG(0, ("Failed to listen on pipe socket %s: %s\n",
182                           pipe_name, strerror(errno)));
183                 goto out;
184         }
185
186         state->ev_ctx = ev_ctx;
187         state->msg_ctx = msg_ctx;
188
189         DEBUG(10, ("Openened pipe socket fd %d for %s\n",
190                    state->fd, pipe_name));
191
192         fde = tevent_add_fd(ev_ctx,
193                             state, state->fd, TEVENT_FD_READ,
194                             named_pipe_listener, state);
195         if (!fde) {
196                 DEBUG(0, ("Failed to add event handler!\n"));
197                 goto out;
198         }
199
200         tevent_fd_set_auto_close(fde);
201         return true;
202
203 out:
204         if (state->fd != -1) {
205                 close(state->fd);
206         }
207         TALLOC_FREE(state);
208         return false;
209 }
210
211 static void named_pipe_listener(struct tevent_context *ev,
212                                 struct tevent_fd *fde,
213                                 uint16_t flags,
214                                 void *private_data)
215 {
216         struct dcerpc_ncacn_listen_state *state =
217                         talloc_get_type_abort(private_data,
218                                               struct dcerpc_ncacn_listen_state);
219         struct sockaddr_un sunaddr;
220         socklen_t len;
221         int sd = -1;
222
223         /* TODO: should we have a limit to the number of clients ? */
224
225         len = sizeof(sunaddr);
226
227         sd = accept(state->fd,
228                     (struct sockaddr *)(void *)&sunaddr, &len);
229
230         if (sd == -1) {
231                 if (errno != EINTR) {
232                         DEBUG(6, ("Failed to get a valid socket [%s]\n",
233                                   strerror(errno)));
234                 }
235                 return;
236         }
237
238         DEBUG(6, ("Accepted socket %d\n", sd));
239
240         named_pipe_accept_function(state->ev_ctx,
241                                    state->msg_ctx,
242                                    state->ep.name,
243                                    sd, NULL, 0);
244 }
245
246
247 /* This is the core of the rpc server.
248  * Accepts connections from clients and process requests using the appropriate
249  * dispatcher table. */
250
251 struct named_pipe_client {
252         const char *pipe_name;
253
254         struct tevent_context *ev;
255         struct messaging_context *msg_ctx;
256
257         uint16_t file_type;
258         uint16_t device_state;
259         uint64_t allocation_size;
260
261         struct tstream_context *tstream;
262
263         struct tsocket_address *client;
264         char *client_name;
265         struct tsocket_address *server;
266         char *server_name;
267
268         struct auth_session_info *session_info;
269
270         struct pipes_struct *p;
271
272         struct tevent_queue *write_queue;
273
274         struct iovec *iov;
275         size_t count;
276
277         named_pipe_termination_fn *term_fn;
278         void *private_data;
279 };
280
281 static int named_pipe_destructor(struct named_pipe_client *npc)
282 {
283         if (npc->term_fn) {
284                 npc->term_fn(npc->private_data);
285         }
286         return 0;
287 }
288
289 static void named_pipe_accept_done(struct tevent_req *subreq);
290
291 void named_pipe_accept_function(struct tevent_context *ev_ctx,
292                                 struct messaging_context *msg_ctx,
293                                 const char *pipe_name, int fd,
294                                 named_pipe_termination_fn *term_fn,
295                                 void *private_data)
296 {
297         struct named_pipe_client *npc;
298         struct tstream_context *plain;
299         struct tevent_req *subreq;
300         int ret;
301
302         npc = talloc_zero(ev_ctx, struct named_pipe_client);
303         if (!npc) {
304                 DEBUG(0, ("Out of memory!\n"));
305                 close(fd);
306                 return;
307         }
308
309         npc->pipe_name = talloc_strdup(npc, pipe_name);
310         if (npc->pipe_name == NULL) {
311                 DEBUG(0, ("Out of memory!\n"));
312                 TALLOC_FREE(npc);
313                 close(fd);
314                 return;
315         }
316         npc->ev = ev_ctx;
317         npc->msg_ctx = msg_ctx;
318         npc->term_fn = term_fn;
319         npc->private_data = private_data;
320
321         talloc_set_destructor(npc, named_pipe_destructor);
322
323         /* make sure socket is in NON blocking state */
324         ret = set_blocking(fd, false);
325         if (ret != 0) {
326                 DEBUG(2, ("Failed to make socket non-blocking\n"));
327                 TALLOC_FREE(npc);
328                 close(fd);
329                 return;
330         }
331
332         ret = tstream_bsd_existing_socket(npc, fd, &plain);
333         if (ret != 0) {
334                 DEBUG(2, ("Failed to create tstream socket\n"));
335                 TALLOC_FREE(npc);
336                 close(fd);
337                 return;
338         }
339
340         npc->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
341         npc->device_state = 0xff | 0x0400 | 0x0100;
342         npc->allocation_size = 4096;
343
344         subreq = tstream_npa_accept_existing_send(npc, npc->ev, plain,
345                                                   npc->file_type,
346                                                   npc->device_state,
347                                                   npc->allocation_size);
348         if (!subreq) {
349                 DEBUG(2, ("Failed to start async accept procedure\n"));
350                 TALLOC_FREE(npc);
351                 close(fd);
352                 return;
353         }
354         tevent_req_set_callback(subreq, named_pipe_accept_done, npc);
355 }
356
357 static void named_pipe_packet_done(struct tevent_req *subreq);
358
359 static void named_pipe_accept_done(struct tevent_req *subreq)
360 {
361         struct auth_session_info_transport *session_info_transport;
362         struct named_pipe_client *npc =
363                 tevent_req_callback_data(subreq, struct named_pipe_client);
364         int error;
365         int ret;
366
367         ret = tstream_npa_accept_existing_recv(subreq, &error, npc,
368                                                 &npc->tstream,
369                                                 &npc->client,
370                                                 &npc->client_name,
371                                                 &npc->server,
372                                                 &npc->server_name,
373                                                 &session_info_transport);
374
375         npc->session_info = talloc_move(npc, &session_info_transport->session_info);
376
377         TALLOC_FREE(subreq);
378         if (ret != 0) {
379                 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
380                           strerror(error)));
381                 TALLOC_FREE(npc);
382                 return;
383         }
384
385         ret = make_server_pipes_struct(npc,
386                                        npc->msg_ctx,
387                                        npc->pipe_name, NCACN_NP,
388                                         false, npc->server, npc->client, npc->session_info,
389                                         &npc->p, &error);
390         if (ret != 0) {
391                 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
392                           strerror(error)));
393                 goto fail;
394         }
395
396         npc->write_queue = tevent_queue_create(npc, "np_server_write_queue");
397         if (!npc->write_queue) {
398                 DEBUG(2, ("Failed to set up write queue!\n"));
399                 goto fail;
400         }
401
402         /* And now start receiving and processing packets */
403         subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
404         if (!subreq) {
405                 DEBUG(2, ("Failed to start receving packets\n"));
406                 goto fail;
407         }
408         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
409         return;
410
411 fail:
412         DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
413                   npc->client_name));
414         /* terminate client connection */
415         talloc_free(npc);
416         return;
417 }
418
419 void named_pipe_packet_process(struct tevent_req *subreq)
420 {
421         struct named_pipe_client *npc =
422                 tevent_req_callback_data(subreq, struct named_pipe_client);
423         struct _output_data *out = &npc->p->out_data;
424         DATA_BLOB recv_buffer = data_blob_null;
425         struct ncacn_packet *pkt;
426         NTSTATUS status;
427         ssize_t data_left;
428         ssize_t data_used;
429         char *data;
430         uint32_t to_send;
431         size_t i;
432         bool ok;
433
434         status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer);
435         TALLOC_FREE(subreq);
436         if (!NT_STATUS_IS_OK(status)) {
437                 goto fail;
438         }
439
440         data_left = recv_buffer.length;
441         data = (char *)recv_buffer.data;
442
443         while (data_left) {
444
445                 data_used = process_incoming_data(npc->p, data, data_left);
446                 if (data_used < 0) {
447                         DEBUG(3, ("Failed to process dceprc request!\n"));
448                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
449                         goto fail;
450                 }
451
452                 data_left -= data_used;
453                 data += data_used;
454         }
455
456         /* Do not leak this buffer, npc is a long lived context */
457         talloc_free(recv_buffer.data);
458         talloc_free(pkt);
459
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;
463         if (to_send > 0) {
464
465                 npc->iov = talloc_zero(npc, struct iovec);
466                 if (!npc->iov) {
467                         status = NT_STATUS_NO_MEMORY;
468                         goto fail;
469                 }
470                 npc->count = 1;
471
472                 npc->iov[0].iov_base = out->frag.data
473                                         + out->current_pdu_sent;
474                 npc->iov[0].iov_len = to_send;
475
476                 out->current_pdu_sent += to_send;
477         }
478
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
481          * the client */
482         while (out->data_sent_length < out->rdata.length) {
483
484                 ok = create_next_pdu(npc->p);
485                 if (!ok) {
486                         DEBUG(3, ("Failed to create next PDU!\n"));
487                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
488                         goto fail;
489                 }
490
491                 npc->iov = talloc_realloc(npc, npc->iov,
492                                             struct iovec, npc->count + 1);
493                 if (!npc->iov) {
494                         status = NT_STATUS_NO_MEMORY;
495                         goto fail;
496                 }
497
498                 npc->iov[npc->count].iov_base = out->frag.data;
499                 npc->iov[npc->count].iov_len = out->frag.length;
500
501                 npc->count++;
502         }
503
504         /* we still don't have a complete request, go back and wait for more
505          * data */
506         if (npc->count == 0) {
507                 /* Wait for the next packet */
508                 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
509                 if (!subreq) {
510                         DEBUG(2, ("Failed to start receving packets\n"));
511                         status = NT_STATUS_NO_MEMORY;
512                         goto fail;
513                 }
514                 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
515                 return;
516         }
517
518         DEBUG(10, ("Sending %u fragments in a total of %u bytes\n",
519                    (unsigned int)npc->count,
520                    (unsigned int)npc->p->out_data.data_sent_length));
521
522         for (i = 0; i < npc->count; i++) {
523                 DEBUG(10, ("Sending PDU number: %d, PDU Length: %u\n",
524                           (unsigned int)i,
525                           (unsigned int)npc->iov[i].iov_len));
526                 dump_data(11, (const uint8_t *)npc->iov[i].iov_base,
527                                 npc->iov[i].iov_len);
528
529                 subreq = tstream_writev_queue_send(npc,
530                                                    npc->ev,
531                                                    npc->tstream,
532                                                    npc->write_queue,
533                                                    (npc->iov + i),
534                                                    1);
535                 if (!subreq) {
536                         DEBUG(2, ("Failed to send packet\n"));
537                         status = NT_STATUS_NO_MEMORY;
538                         goto fail;
539                 }
540                 tevent_req_set_callback(subreq, named_pipe_packet_done, npc);
541         }
542
543         return;
544
545 fail:
546         DEBUG(2, ("Fatal error(%s). "
547                   "Terminating client(%s) connection!\n",
548                   nt_errstr(status), npc->client_name));
549         /* terminate client connection */
550         talloc_free(npc);
551         return;
552 }
553
554 static void named_pipe_packet_done(struct tevent_req *subreq)
555 {
556         struct named_pipe_client *npc =
557                 tevent_req_callback_data(subreq, struct named_pipe_client);
558         int sys_errno;
559         int ret;
560
561         ret = tstream_writev_queue_recv(subreq, &sys_errno);
562         TALLOC_FREE(subreq);
563         if (ret == -1) {
564                 DEBUG(2, ("Writev failed!\n"));
565                 goto fail;
566         }
567
568         if (tevent_queue_length(npc->write_queue) > 0) {
569                 return;
570         }
571
572         /* clear out any data that may have been left around */
573         npc->count = 0;
574         TALLOC_FREE(npc->iov);
575         data_blob_free(&npc->p->in_data.data);
576         data_blob_free(&npc->p->out_data.frag);
577         data_blob_free(&npc->p->out_data.rdata);
578
579         talloc_free_children(npc->p->mem_ctx);
580
581         /* Wait for the next packet */
582         subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
583         if (!subreq) {
584                 DEBUG(2, ("Failed to start receving packets\n"));
585                 sys_errno = ENOMEM;
586                 goto fail;
587         }
588         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
589         return;
590
591 fail:
592         DEBUG(2, ("Fatal error(%s). "
593                   "Terminating client(%s) connection!\n",
594                   strerror(sys_errno), npc->client_name));
595         /* terminate client connection */
596         talloc_free(npc);
597         return;
598 }
599
600 /********************************************************************
601  * Start listening on the tcp/ip socket
602  ********************************************************************/
603
604 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
605                                         struct tevent_fd *fde,
606                                         uint16_t flags,
607                                         void *private_data);
608
609 int create_tcpip_socket(const struct sockaddr_storage *ifss, uint16_t *port)
610 {
611         int fd = -1;
612
613         if (*port == 0) {
614                 uint16_t i;
615
616                 for (i = SERVER_TCP_LOW_PORT; i <= SERVER_TCP_HIGH_PORT; i++) {
617                         fd = open_socket_in(SOCK_STREAM,
618                                             i,
619                                             0,
620                                             ifss,
621                                             false);
622                         if (fd >= 0) {
623                                 *port = i;
624                                 break;
625                         }
626                 }
627         } else {
628                 fd = open_socket_in(SOCK_STREAM,
629                                     *port,
630                                     0,
631                                     ifss,
632                                     true);
633         }
634         if (fd == -1) {
635                 DEBUG(0, ("Failed to create socket on port %u!\n", *port));
636                 return -1;
637         }
638
639         DEBUG(10, ("Opened tcpip socket fd %d for port %u\n", fd, *port));
640
641         return fd;
642 }
643
644 uint16_t setup_dcerpc_ncacn_tcpip_socket(struct tevent_context *ev_ctx,
645                                          struct messaging_context *msg_ctx,
646                                          const struct sockaddr_storage *ifss,
647                                          uint16_t port)
648 {
649         struct dcerpc_ncacn_listen_state *state;
650         struct tevent_fd *fde;
651         int rc;
652
653         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
654         if (state == NULL) {
655                 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Out of memory\n"));
656                 return 0;
657         }
658
659         state->fd = -1;
660         state->ep.port = port;
661         state->disconnect_fn = NULL;
662
663         state->fd = create_tcpip_socket(ifss, &state->ep.port);
664         if (state->fd == -1) {
665                 goto out;
666         }
667
668         state->ev_ctx = ev_ctx;
669         state->msg_ctx = msg_ctx;
670
671         /* ready to listen */
672         set_socket_options(state->fd, "SO_KEEPALIVE");
673         set_socket_options(state->fd, lp_socket_options());
674
675         /* Set server socket to non-blocking for the accept. */
676         set_blocking(state->fd, false);
677
678         rc = listen(state->fd, SMBD_LISTEN_BACKLOG);
679         if (rc == -1) {
680                 DEBUG(0,("setup_tcpip_socket: listen - %s\n", strerror(errno)));
681                 goto out;
682         }
683
684         DEBUG(10, ("setup_tcpip_socket: openened socket fd %d for port %u\n",
685                    state->fd, state->ep.port));
686
687         fde = tevent_add_fd(state->ev_ctx,
688                             state,
689                             state->fd,
690                             TEVENT_FD_READ,
691                             dcerpc_ncacn_tcpip_listener,
692                             state);
693         if (fde == NULL) {
694                 DEBUG(0, ("setup_tcpip_socket: Failed to add event handler!\n"));
695                 goto out;
696         }
697
698         tevent_fd_set_auto_close(fde);
699
700         return state->ep.port;
701 out:
702         if (state->fd != -1) {
703                 close(state->fd);
704         }
705         TALLOC_FREE(state);
706
707         return 0;
708 }
709
710 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
711                                         struct tevent_fd *fde,
712                                         uint16_t flags,
713                                         void *private_data)
714 {
715         struct dcerpc_ncacn_listen_state *state =
716                         talloc_get_type_abort(private_data,
717                                               struct dcerpc_ncacn_listen_state);
718         struct tsocket_address *cli_addr = NULL;
719         struct tsocket_address *srv_addr = NULL;
720         struct sockaddr_storage addr;
721         socklen_t in_addrlen = sizeof(addr);
722         int s = -1;
723         int rc;
724
725         s = accept(state->fd, (struct sockaddr *)(void *) &addr, &in_addrlen);
726         if (s == -1) {
727                 if (errno != EINTR) {
728                         DEBUG(0,("tcpip_listener accept: %s\n",
729                                  strerror(errno)));
730                 }
731                 return;
732         }
733
734         rc = tsocket_address_bsd_from_sockaddr(state,
735                                                (struct sockaddr *)(void *) &addr,
736                                                in_addrlen,
737                                                &cli_addr);
738         if (rc < 0) {
739                 close(s);
740                 return;
741         }
742
743         rc = getsockname(s, (struct sockaddr *)(void *) &addr, &in_addrlen);
744         if (rc < 0) {
745                 close(s);
746                 return;
747         }
748
749         rc = tsocket_address_bsd_from_sockaddr(state,
750                                                (struct sockaddr *)(void *) &addr,
751                                                in_addrlen,
752                                                &srv_addr);
753         if (rc < 0) {
754                 close(s);
755                 return;
756         }
757
758         DEBUG(6, ("tcpip_listener: Accepted socket %d\n", s));
759
760         dcerpc_ncacn_accept(state->ev_ctx,
761                             state->msg_ctx,
762                             NCACN_IP_TCP,
763                             NULL,
764                             cli_addr,
765                             srv_addr,
766                             s,
767                             NULL);
768 }
769
770 /********************************************************************
771  * Start listening on the ncalrpc socket
772  ********************************************************************/
773
774 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
775                                     struct tevent_fd *fde,
776                                     uint16_t flags,
777                                     void *private_data);
778
779 int create_dcerpc_ncalrpc_socket(const char *name)
780 {
781         int fd = -1;
782
783         if (name == NULL) {
784                 name = "DEFAULT";
785         }
786
787         if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
788                 DEBUG(0, ("Failed to create ncalrpc directory %s - %s\n",
789                           lp_ncalrpc_dir(), strerror(errno)));
790                 return -1;
791         }
792
793         fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
794         if (fd == -1) {
795                 DEBUG(0, ("Failed to create ncalrpc socket! [%s/%s]\n",
796                           lp_ncalrpc_dir(), name));
797                 return -1;
798         }
799
800         DEBUG(10, ("Openened ncalrpc socket fd %d for %s\n", fd, name));
801
802         return fd;
803 }
804
805 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
806                                  struct messaging_context *msg_ctx,
807                                  const char *name,
808                                  dcerpc_ncacn_disconnect_fn fn)
809 {
810         struct dcerpc_ncacn_listen_state *state;
811         struct tevent_fd *fde;
812         int rc;
813
814         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
815         if (state == NULL) {
816                 DEBUG(0, ("Out of memory\n"));
817                 return false;
818         }
819
820         state->fd = -1;
821         state->disconnect_fn = fn;
822
823         if (name == NULL) {
824                 name = "DEFAULT";
825         }
826
827         state->ep.name = talloc_strdup(state, name);
828         if (state->ep.name == NULL) {
829                 DEBUG(0, ("Out of memory\n"));
830                 talloc_free(state);
831                 return false;
832         }
833
834         state->fd = create_dcerpc_ncalrpc_socket(name);
835         if (state->fd == -1) {
836                 goto out;
837         }
838
839         rc = listen(state->fd, 5);
840         if (rc < 0) {
841                 DEBUG(0, ("Failed to listen on ncalrpc socket %s: %s\n",
842                           name, strerror(errno)));
843                 goto out;
844         }
845
846         state->ev_ctx = ev_ctx;
847         state->msg_ctx = msg_ctx;
848
849         /* Set server socket to non-blocking for the accept. */
850         set_blocking(state->fd, false);
851
852         fde = tevent_add_fd(state->ev_ctx,
853                             state,
854                             state->fd,
855                             TEVENT_FD_READ,
856                             dcerpc_ncalrpc_listener,
857                             state);
858         if (fde == NULL) {
859                 DEBUG(0, ("Failed to add event handler for ncalrpc!\n"));
860                 goto out;
861         }
862
863         tevent_fd_set_auto_close(fde);
864
865         return true;
866 out:
867         if (state->fd != -1) {
868                 close(state->fd);
869         }
870         TALLOC_FREE(state);
871
872         return 0;
873 }
874
875 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
876                                         struct tevent_fd *fde,
877                                         uint16_t flags,
878                                         void *private_data)
879 {
880         struct dcerpc_ncacn_listen_state *state =
881                         talloc_get_type_abort(private_data,
882                                               struct dcerpc_ncacn_listen_state);
883         struct tsocket_address *cli_addr = NULL;
884         struct sockaddr_un sunaddr;
885         struct sockaddr *addr = (struct sockaddr *)(void *)&sunaddr;
886         socklen_t len = sizeof(sunaddr);
887         int sd = -1;
888         int rc;
889
890         ZERO_STRUCT(sunaddr);
891
892         sd = accept(state->fd, addr, &len);
893         if (sd == -1) {
894                 if (errno != EINTR) {
895                         DEBUG(0, ("ncalrpc accept() failed: %s\n", strerror(errno)));
896                 }
897                 return;
898         }
899
900         rc = tsocket_address_bsd_from_sockaddr(state,
901                                                addr, len,
902                                                &cli_addr);
903         if (rc < 0) {
904                 close(sd);
905                 return;
906         }
907
908         DEBUG(10, ("Accepted ncalrpc socket %d\n", sd));
909
910         dcerpc_ncacn_accept(state->ev_ctx,
911                             state->msg_ctx,
912                             NCALRPC,
913                             state->ep.name,
914                             cli_addr, NULL, sd,
915                             state->disconnect_fn);
916 }
917
918 struct dcerpc_ncacn_conn {
919         enum dcerpc_transport_t transport;
920
921         int sock;
922
923         struct pipes_struct *p;
924         dcerpc_ncacn_disconnect_fn disconnect_fn;
925
926         struct tevent_context *ev_ctx;
927         struct messaging_context *msg_ctx;
928
929         struct tstream_context *tstream;
930         struct tevent_queue *send_queue;
931
932         struct tsocket_address *client;
933         char *client_name;
934         struct tsocket_address *server;
935         char *server_name;
936         struct auth_session_info *session_info;
937
938         struct iovec *iov;
939         size_t count;
940 };
941
942 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
943 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
944
945 void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
946                          struct messaging_context *msg_ctx,
947                          enum dcerpc_transport_t transport,
948                          const char *name,
949                          struct tsocket_address *cli_addr,
950                          struct tsocket_address *srv_addr,
951                          int s,
952                          dcerpc_ncacn_disconnect_fn fn) {
953         struct dcerpc_ncacn_conn *ncacn_conn;
954         struct tevent_req *subreq;
955         bool system_user = false;
956         char *pipe_name;
957         NTSTATUS status;
958         int sys_errno;
959         uid_t uid;
960         gid_t gid;
961         int rc;
962
963         DEBUG(10, ("dcerpc_ncacn_accept\n"));
964
965         ncacn_conn = talloc_zero(ev_ctx, struct dcerpc_ncacn_conn);
966         if (ncacn_conn == NULL) {
967                 DEBUG(0, ("Out of memory!\n"));
968                 close(s);
969                 return;
970         }
971
972         ncacn_conn->transport = transport;
973         ncacn_conn->ev_ctx = ev_ctx;
974         ncacn_conn->msg_ctx = msg_ctx;
975         ncacn_conn->sock = s;
976         ncacn_conn->disconnect_fn = fn;
977
978         ncacn_conn->client = talloc_move(ncacn_conn, &cli_addr);
979         if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
980                 ncacn_conn->client_name =
981                         tsocket_address_inet_addr_string(ncacn_conn->client,
982                                                          ncacn_conn);
983         } else {
984                 ncacn_conn->client_name =
985                         tsocket_address_unix_path(ncacn_conn->client,
986                                                   ncacn_conn);
987         }
988         if (ncacn_conn->client_name == NULL) {
989                 DEBUG(0, ("Out of memory!\n"));
990                 talloc_free(ncacn_conn);
991                 close(s);
992                 return;
993         }
994
995         if (srv_addr != NULL) {
996                 ncacn_conn->server = talloc_move(ncacn_conn, &srv_addr);
997
998                 ncacn_conn->server_name =
999                         tsocket_address_inet_addr_string(ncacn_conn->server,
1000                                                          ncacn_conn);
1001                 if (ncacn_conn->server_name == NULL) {
1002                         DEBUG(0, ("Out of memory!\n"));
1003                         talloc_free(ncacn_conn);
1004                         close(s);
1005                         return;
1006                 }
1007         }
1008
1009         switch (transport) {
1010                 case NCACN_IP_TCP:
1011                         pipe_name = tsocket_address_string(ncacn_conn->client,
1012                                                            ncacn_conn);
1013                         if (pipe_name == NULL) {
1014                                 close(s);
1015                                 talloc_free(ncacn_conn);
1016                                 return;
1017                         }
1018
1019                         break;
1020                 case NCALRPC:
1021                         rc = getpeereid(s, &uid, &gid);
1022                         if (rc < 0) {
1023                                 DEBUG(2, ("Failed to get ncalrpc connecting "
1024                                           "uid - %s!\n", strerror(errno)));
1025                         } else {
1026                                 if (uid == sec_initial_uid()) {
1027                                         system_user = true;
1028                                 }
1029                         }
1030                         /* FALL TROUGH */
1031                 case NCACN_NP:
1032                         pipe_name = talloc_strdup(ncacn_conn,
1033                                                   name);
1034                         if (pipe_name == NULL) {
1035                                 close(s);
1036                                 talloc_free(ncacn_conn);
1037                                 return;
1038                         }
1039                         break;
1040                 default:
1041                         DEBUG(0, ("unknown dcerpc transport: %u!\n",
1042                                   transport));
1043                         talloc_free(ncacn_conn);
1044                         close(s);
1045                         return;
1046         }
1047
1048         rc = set_blocking(s, false);
1049         if (rc < 0) {
1050                 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1051                 talloc_free(ncacn_conn);
1052                 close(s);
1053                 return;
1054         }
1055
1056         /*
1057          * As soon as we have tstream_bsd_existing_socket set up it will
1058          * take care of closing the socket.
1059          */
1060         rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream);
1061         if (rc < 0) {
1062                 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1063                 talloc_free(ncacn_conn);
1064                 close(s);
1065                 return;
1066         }
1067
1068         if (ncacn_conn->session_info == NULL) {
1069                 status = auth_anonymous_session_info(ncacn_conn,
1070                                                      &ncacn_conn->session_info);
1071                 if (!NT_STATUS_IS_OK(status)) {
1072                         DEBUG(2, ("Failed to create "
1073                                   "auth_anonymous_session_info - %s\n",
1074                                   nt_errstr(status)));
1075                         talloc_free(ncacn_conn);
1076                         return;
1077                 }
1078         }
1079
1080         rc = make_server_pipes_struct(ncacn_conn,
1081                                       ncacn_conn->msg_ctx,
1082                                       pipe_name,
1083                                       ncacn_conn->transport,
1084                                       system_user,
1085                                       ncacn_conn->server,
1086                                       ncacn_conn->client,
1087                                       ncacn_conn->session_info,
1088                                       &ncacn_conn->p,
1089                                       &sys_errno);
1090         if (rc < 0) {
1091                 DEBUG(2, ("Failed to create pipe struct - %s",
1092                           strerror(sys_errno)));
1093                 talloc_free(ncacn_conn);
1094                 return;
1095         }
1096
1097         ncacn_conn->send_queue = tevent_queue_create(ncacn_conn,
1098                                                         "dcerpc send queue");
1099         if (ncacn_conn->send_queue == NULL) {
1100                 DEBUG(0, ("Out of memory!\n"));
1101                 talloc_free(ncacn_conn);
1102                 return;
1103         }
1104
1105         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1106                                                ncacn_conn->ev_ctx,
1107                                                ncacn_conn->tstream);
1108         if (subreq == NULL) {
1109                 DEBUG(2, ("Failed to send ncacn packet\n"));
1110                 talloc_free(ncacn_conn);
1111                 return;
1112         }
1113
1114         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1115
1116         DEBUG(10, ("dcerpc_ncacn_accept done\n"));
1117
1118         return;
1119 }
1120
1121 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq)
1122 {
1123         struct dcerpc_ncacn_conn *ncacn_conn =
1124                 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1125
1126         struct _output_data *out = &ncacn_conn->p->out_data;
1127         DATA_BLOB recv_buffer = data_blob_null;
1128         struct ncacn_packet *pkt;
1129         ssize_t data_left;
1130         ssize_t data_used;
1131         uint32_t to_send;
1132         char *data;
1133         NTSTATUS status;
1134         bool ok;
1135
1136         status = dcerpc_read_ncacn_packet_recv(subreq, ncacn_conn, &pkt, &recv_buffer);
1137         TALLOC_FREE(subreq);
1138         if (!NT_STATUS_IS_OK(status)) {
1139                 if (ncacn_conn->disconnect_fn != NULL) {
1140                         ok = ncacn_conn->disconnect_fn(ncacn_conn->p);
1141                         if (!ok) {
1142                                 DEBUG(3, ("Failed to call disconnect function\n"));
1143                         }
1144                 }
1145                 goto fail;
1146         }
1147
1148         data_left = recv_buffer.length;
1149         data = (char *) recv_buffer.data;
1150
1151         while (data_left) {
1152                 data_used = process_incoming_data(ncacn_conn->p, data, data_left);
1153                 if (data_used < 0) {
1154                         DEBUG(3, ("Failed to process dcerpc request!\n"));
1155                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
1156                         goto fail;
1157                 }
1158
1159                 data_left -= data_used;
1160                 data += data_used;
1161         }
1162
1163         /* Do not leak this buffer */
1164         talloc_free(recv_buffer.data);
1165         talloc_free(pkt);
1166
1167         /*
1168          * This is needed because of the way DCERPC binds work in the RPC
1169          * marshalling code
1170          */
1171         to_send = out->frag.length - out->current_pdu_sent;
1172         if (to_send > 0) {
1173
1174                 DEBUG(10, ("Current_pdu_len = %u, "
1175                            "current_pdu_sent = %u "
1176                            "Returning %u bytes\n",
1177                            (unsigned int)out->frag.length,
1178                            (unsigned int)out->current_pdu_sent,
1179                            (unsigned int)to_send));
1180
1181                 ncacn_conn->iov = talloc_zero(ncacn_conn, struct iovec);
1182                 if (ncacn_conn->iov == NULL) {
1183                         status = NT_STATUS_NO_MEMORY;
1184                         DEBUG(3, ("Out of memory!\n"));
1185                         goto fail;
1186                 }
1187                 ncacn_conn->count = 1;
1188
1189                 ncacn_conn->iov[0].iov_base = out->frag.data
1190                                             + out->current_pdu_sent;
1191                 ncacn_conn->iov[0].iov_len = to_send;
1192
1193                 out->current_pdu_sent += to_send;
1194         }
1195
1196         /*
1197          * This condition is false for bind packets, or when we haven't yet got
1198          * a full request, and need to wait for more data from the client
1199          */
1200         while (out->data_sent_length < out->rdata.length) {
1201                 ok = create_next_pdu(ncacn_conn->p);
1202                 if (!ok) {
1203                         DEBUG(3, ("Failed to create next PDU!\n"));
1204                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
1205                         goto fail;
1206                 }
1207
1208                 ncacn_conn->iov = talloc_realloc(ncacn_conn,
1209                                                  ncacn_conn->iov,
1210                                                  struct iovec,
1211                                                  ncacn_conn->count + 1);
1212                 if (ncacn_conn->iov == NULL) {
1213                         DEBUG(3, ("Out of memory!\n"));
1214                         status = NT_STATUS_NO_MEMORY;
1215                         goto fail;
1216                 }
1217
1218                 ncacn_conn->iov[ncacn_conn->count].iov_base = out->frag.data;
1219                 ncacn_conn->iov[ncacn_conn->count].iov_len = out->frag.length;
1220
1221                 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
1222                            (unsigned int) ncacn_conn->count,
1223                            (unsigned int) ncacn_conn->iov[ncacn_conn->count].iov_len));
1224                 dump_data(11, (const uint8_t *) ncacn_conn->iov[ncacn_conn->count].iov_base,
1225                               ncacn_conn->iov[ncacn_conn->count].iov_len);
1226                 ncacn_conn->count++;
1227         }
1228
1229         /*
1230          * We still don't have a complete request, go back and wait for more
1231          * data.
1232          */
1233         if (ncacn_conn->count == 0) {
1234                 /* Wait for the next packet */
1235                 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1236                                                        ncacn_conn->ev_ctx,
1237                                                        ncacn_conn->tstream);
1238                 if (subreq == NULL) {
1239                         DEBUG(2, ("Failed to start receving packets\n"));
1240                         status = NT_STATUS_NO_MEMORY;
1241                         goto fail;
1242                 }
1243                 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1244                 return;
1245         }
1246
1247         DEBUG(10, ("Sending a total of %u bytes\n",
1248                    (unsigned int)ncacn_conn->p->out_data.data_sent_length));
1249
1250         subreq = tstream_writev_queue_send(ncacn_conn,
1251                                            ncacn_conn->ev_ctx,
1252                                            ncacn_conn->tstream,
1253                                            ncacn_conn->send_queue,
1254                                            ncacn_conn->iov,
1255                                            ncacn_conn->count);
1256         if (subreq == NULL) {
1257                 DEBUG(2, ("Failed to send packet\n"));
1258                 status = NT_STATUS_NO_MEMORY;
1259                 goto fail;
1260         }
1261
1262         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_done, ncacn_conn);
1263         return;
1264
1265 fail:
1266         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1267                   ncacn_conn->client_name, nt_errstr(status)));
1268
1269         /* Terminate client connection */
1270         talloc_free(ncacn_conn);
1271         return;
1272 }
1273
1274 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq)
1275 {
1276         struct dcerpc_ncacn_conn *ncacn_conn =
1277                 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1278         NTSTATUS status = NT_STATUS_OK;
1279         int sys_errno;
1280         int rc;
1281
1282         rc = tstream_writev_queue_recv(subreq, &sys_errno);
1283         TALLOC_FREE(subreq);
1284         if (rc < 0) {
1285                 DEBUG(2, ("Writev failed!\n"));
1286                 status = map_nt_error_from_unix(sys_errno);
1287                 goto fail;
1288         }
1289
1290         /* clear out any data that may have been left around */
1291         ncacn_conn->count = 0;
1292         TALLOC_FREE(ncacn_conn->iov);
1293         data_blob_free(&ncacn_conn->p->in_data.data);
1294         data_blob_free(&ncacn_conn->p->out_data.frag);
1295         data_blob_free(&ncacn_conn->p->out_data.rdata);
1296
1297         talloc_free_children(ncacn_conn->p->mem_ctx);
1298
1299         /* Wait for the next packet */
1300         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1301                                                ncacn_conn->ev_ctx,
1302                                                ncacn_conn->tstream);
1303         if (subreq == NULL) {
1304                 DEBUG(2, ("Failed to start receving packets\n"));
1305                 status = NT_STATUS_NO_MEMORY;
1306                 goto fail;
1307         }
1308
1309         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1310         return;
1311
1312 fail:
1313         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1314                   ncacn_conn->client_name, nt_errstr(status)));
1315
1316         /* Terminate client connection */
1317         talloc_free(ncacn_conn);
1318         return;
1319 }
1320
1321 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */