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