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