s3-rpc_server: Add create_dcerpc_ncalrpc_socket().
[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 int create_dcerpc_ncalrpc_socket(const char *name)
823 {
824         int fd = -1;
825
826         if (name == NULL) {
827                 name = "DEFAULT";
828         }
829
830         if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
831                 DEBUG(0, ("Failed to create ncalrpc directory %s - %s\n",
832                           lp_ncalrpc_dir(), strerror(errno)));
833                 return -1;
834         }
835
836         fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
837         if (fd == -1) {
838                 DEBUG(0, ("Failed to create ncalrpc socket! [%s/%s]\n",
839                           lp_ncalrpc_dir(), name));
840                 return -1;
841         }
842
843         DEBUG(10, ("Openened ncalrpc socket fd %d for %s\n", fd, name));
844
845         return fd;
846 }
847
848 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
849                                  struct messaging_context *msg_ctx,
850                                  const char *name,
851                                  dcerpc_ncacn_disconnect_fn fn)
852 {
853         struct dcerpc_ncacn_listen_state *state;
854         struct tevent_fd *fde;
855
856         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
857         if (state == NULL) {
858                 DEBUG(0, ("Out of memory\n"));
859                 return false;
860         }
861
862         state->fd = -1;
863         state->disconnect_fn = fn;
864
865         if (name == NULL) {
866                 name = "DEFAULT";
867         }
868
869         state->ep.name = talloc_strdup(state, name);
870         if (state->ep.name == NULL) {
871                 DEBUG(0, ("Out of memory\n"));
872                 talloc_free(state);
873                 return false;
874         }
875
876         state->fd = create_dcerpc_ncalrpc_socket(name);
877         if (state->fd == -1) {
878                 goto out;
879         }
880
881         state->ev_ctx = ev_ctx;
882         state->msg_ctx = msg_ctx;
883
884         /* Set server socket to non-blocking for the accept. */
885         set_blocking(state->fd, false);
886
887         fde = tevent_add_fd(state->ev_ctx,
888                             state,
889                             state->fd,
890                             TEVENT_FD_READ,
891                             dcerpc_ncalrpc_listener,
892                             state);
893         if (fde == NULL) {
894                 DEBUG(0, ("Failed to add event handler for ncalrpc!\n"));
895                 goto out;
896         }
897
898         tevent_fd_set_auto_close(fde);
899
900         return true;
901 out:
902         if (state->fd != -1) {
903                 close(state->fd);
904         }
905         TALLOC_FREE(state);
906
907         return 0;
908 }
909
910 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
911                                         struct tevent_fd *fde,
912                                         uint16_t flags,
913                                         void *private_data)
914 {
915         struct dcerpc_ncacn_listen_state *state =
916                         talloc_get_type_abort(private_data,
917                                               struct dcerpc_ncacn_listen_state);
918         struct tsocket_address *cli_addr = NULL;
919         struct sockaddr_un sunaddr;
920         struct sockaddr *addr = (struct sockaddr *)(void *)&sunaddr;
921         socklen_t len = sizeof(sunaddr);
922         int sd = -1;
923         int rc;
924
925         ZERO_STRUCT(sunaddr);
926
927         sd = accept(state->fd, addr, &len);
928         if (sd == -1) {
929                 if (errno != EINTR) {
930                         DEBUG(0, ("ncalrpc accept() failed: %s\n", strerror(errno)));
931                 }
932                 return;
933         }
934
935         rc = tsocket_address_bsd_from_sockaddr(state,
936                                                addr, len,
937                                                &cli_addr);
938         if (rc < 0) {
939                 close(sd);
940                 return;
941         }
942
943         DEBUG(10, ("Accepted ncalrpc socket %d\n", sd));
944
945         dcerpc_ncacn_accept(state->ev_ctx,
946                             state->msg_ctx,
947                             NCALRPC,
948                             state->ep.name,
949                             cli_addr, NULL, sd,
950                             state->disconnect_fn);
951 }
952
953 struct dcerpc_ncacn_conn {
954         enum dcerpc_transport_t transport;
955
956         int sock;
957
958         struct pipes_struct *p;
959         dcerpc_ncacn_disconnect_fn disconnect_fn;
960
961         struct tevent_context *ev_ctx;
962         struct messaging_context *msg_ctx;
963
964         struct tstream_context *tstream;
965         struct tevent_queue *send_queue;
966
967         struct tsocket_address *client;
968         char *client_name;
969         struct tsocket_address *server;
970         char *server_name;
971         struct auth_session_info *session_info;
972
973         struct iovec *iov;
974         size_t count;
975 };
976
977 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
978 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
979
980 void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
981                          struct messaging_context *msg_ctx,
982                          enum dcerpc_transport_t transport,
983                          const char *name,
984                          struct tsocket_address *cli_addr,
985                          struct tsocket_address *srv_addr,
986                          int s,
987                          dcerpc_ncacn_disconnect_fn fn) {
988         struct dcerpc_ncacn_conn *ncacn_conn;
989         struct tevent_req *subreq;
990         bool system_user = false;
991         char *pipe_name;
992         NTSTATUS status;
993         int sys_errno;
994         uid_t uid;
995         int rc;
996
997         DEBUG(10, ("dcerpc_ncacn_accept\n"));
998
999         ncacn_conn = talloc_zero(ev_ctx, struct dcerpc_ncacn_conn);
1000         if (ncacn_conn == NULL) {
1001                 DEBUG(0, ("Out of memory!\n"));
1002                 close(s);
1003                 return;
1004         }
1005
1006         ncacn_conn->transport = transport;
1007         ncacn_conn->ev_ctx = ev_ctx;
1008         ncacn_conn->msg_ctx = msg_ctx;
1009         ncacn_conn->sock = s;
1010         ncacn_conn->disconnect_fn = fn;
1011
1012         ncacn_conn->client = talloc_move(ncacn_conn, &cli_addr);
1013         if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
1014                 ncacn_conn->client_name =
1015                         tsocket_address_inet_addr_string(ncacn_conn->client,
1016                                                          ncacn_conn);
1017         } else {
1018                 ncacn_conn->client_name =
1019                         tsocket_address_unix_path(ncacn_conn->client,
1020                                                   ncacn_conn);
1021         }
1022         if (ncacn_conn->client_name == NULL) {
1023                 DEBUG(0, ("Out of memory!\n"));
1024                 talloc_free(ncacn_conn);
1025                 close(s);
1026                 return;
1027         }
1028
1029         if (srv_addr != NULL) {
1030                 ncacn_conn->server = talloc_move(ncacn_conn, &srv_addr);
1031
1032                 ncacn_conn->server_name =
1033                         tsocket_address_inet_addr_string(ncacn_conn->server,
1034                                                          ncacn_conn);
1035                 if (ncacn_conn->server_name == NULL) {
1036                         DEBUG(0, ("Out of memory!\n"));
1037                         talloc_free(ncacn_conn);
1038                         close(s);
1039                         return;
1040                 }
1041         }
1042
1043         switch (transport) {
1044                 case NCACN_IP_TCP:
1045                         pipe_name = tsocket_address_string(ncacn_conn->client,
1046                                                            ncacn_conn);
1047                         if (pipe_name == NULL) {
1048                                 close(s);
1049                                 talloc_free(ncacn_conn);
1050                                 return;
1051                         }
1052
1053                         break;
1054                 case NCALRPC:
1055                         rc = sys_getpeereid(s, &uid);
1056                         if (rc < 0) {
1057                                 DEBUG(2, ("Failed to get ncalrpc connecting uid!"));
1058                         } else {
1059                                 if (uid == sec_initial_uid()) {
1060                                         system_user = true;
1061                                 }
1062                         }
1063                 case NCACN_NP:
1064                         pipe_name = talloc_strdup(ncacn_conn,
1065                                                   name);
1066                         if (pipe_name == NULL) {
1067                                 close(s);
1068                                 talloc_free(ncacn_conn);
1069                                 return;
1070                         }
1071                         break;
1072                 default:
1073                         DEBUG(0, ("unknown dcerpc transport: %u!\n",
1074                                   transport));
1075                         talloc_free(ncacn_conn);
1076                         close(s);
1077                         return;
1078         }
1079
1080         rc = set_blocking(s, false);
1081         if (rc < 0) {
1082                 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1083                 talloc_free(ncacn_conn);
1084                 close(s);
1085                 return;
1086         }
1087
1088         /*
1089          * As soon as we have tstream_bsd_existing_socket set up it will
1090          * take care of closing the socket.
1091          */
1092         rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream);
1093         if (rc < 0) {
1094                 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1095                 talloc_free(ncacn_conn);
1096                 close(s);
1097                 return;
1098         }
1099
1100         if (ncacn_conn->session_info == NULL) {
1101                 status = auth_anonymous_session_info(ncacn_conn,
1102                                                      &ncacn_conn->session_info);
1103                 if (!NT_STATUS_IS_OK(status)) {
1104                         DEBUG(2, ("Failed to create "
1105                                   "auth_anonymous_session_info - %s\n",
1106                                   nt_errstr(status)));
1107                         talloc_free(ncacn_conn);
1108                         return;
1109                 }
1110         }
1111
1112         rc = make_server_pipes_struct(ncacn_conn,
1113                                       ncacn_conn->msg_ctx,
1114                                       pipe_name,
1115                                       ncacn_conn->transport,
1116                                       system_user,
1117                                       ncacn_conn->server,
1118                                       ncacn_conn->client,
1119                                       ncacn_conn->session_info,
1120                                       &ncacn_conn->p,
1121                                       &sys_errno);
1122         if (rc < 0) {
1123                 DEBUG(2, ("Failed to create pipe struct - %s",
1124                           strerror(sys_errno)));
1125                 talloc_free(ncacn_conn);
1126                 return;
1127         }
1128
1129         ncacn_conn->send_queue = tevent_queue_create(ncacn_conn,
1130                                                         "dcerpc send queue");
1131         if (ncacn_conn->send_queue == NULL) {
1132                 DEBUG(0, ("Out of memory!\n"));
1133                 talloc_free(ncacn_conn);
1134                 return;
1135         }
1136
1137         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1138                                                ncacn_conn->ev_ctx,
1139                                                ncacn_conn->tstream);
1140         if (subreq == NULL) {
1141                 DEBUG(2, ("Failed to send ncacn packet\n"));
1142                 talloc_free(ncacn_conn);
1143                 return;
1144         }
1145
1146         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1147
1148         DEBUG(10, ("dcerpc_ncacn_accept done\n"));
1149
1150         return;
1151 }
1152
1153 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq)
1154 {
1155         struct dcerpc_ncacn_conn *ncacn_conn =
1156                 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1157
1158         struct _output_data *out = &ncacn_conn->p->out_data;
1159         DATA_BLOB recv_buffer = data_blob_null;
1160         struct ncacn_packet *pkt;
1161         ssize_t data_left;
1162         ssize_t data_used;
1163         uint32_t to_send;
1164         char *data;
1165         NTSTATUS status;
1166         bool ok;
1167
1168         status = dcerpc_read_ncacn_packet_recv(subreq, ncacn_conn, &pkt, &recv_buffer);
1169         TALLOC_FREE(subreq);
1170         if (!NT_STATUS_IS_OK(status)) {
1171                 if (ncacn_conn->disconnect_fn != NULL) {
1172                         ok = ncacn_conn->disconnect_fn(ncacn_conn->p);
1173                         if (!ok) {
1174                                 DEBUG(3, ("Failed to call disconnect function\n"));
1175                         }
1176                 }
1177                 goto fail;
1178         }
1179
1180         data_left = recv_buffer.length;
1181         data = (char *) recv_buffer.data;
1182
1183         while (data_left) {
1184                 data_used = process_incoming_data(ncacn_conn->p, data, data_left);
1185                 if (data_used < 0) {
1186                         DEBUG(3, ("Failed to process dcerpc request!\n"));
1187                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
1188                         goto fail;
1189                 }
1190
1191                 data_left -= data_used;
1192                 data += data_used;
1193         }
1194
1195         /* Do not leak this buffer */
1196         talloc_free(recv_buffer.data);
1197         talloc_free(pkt);
1198
1199         /*
1200          * This is needed because of the way DCERPC binds work in the RPC
1201          * marshalling code
1202          */
1203         to_send = out->frag.length - out->current_pdu_sent;
1204         if (to_send > 0) {
1205
1206                 DEBUG(10, ("Current_pdu_len = %u, "
1207                            "current_pdu_sent = %u "
1208                            "Returning %u bytes\n",
1209                            (unsigned int)out->frag.length,
1210                            (unsigned int)out->current_pdu_sent,
1211                            (unsigned int)to_send));
1212
1213                 ncacn_conn->iov = talloc_zero(ncacn_conn, struct iovec);
1214                 if (ncacn_conn->iov == NULL) {
1215                         status = NT_STATUS_NO_MEMORY;
1216                         DEBUG(3, ("Out of memory!\n"));
1217                         goto fail;
1218                 }
1219                 ncacn_conn->count = 1;
1220
1221                 ncacn_conn->iov[0].iov_base = out->frag.data
1222                                             + out->current_pdu_sent;
1223                 ncacn_conn->iov[0].iov_len = to_send;
1224
1225                 out->current_pdu_sent += to_send;
1226         }
1227
1228         /*
1229          * This condition is false for bind packets, or when we haven't yet got
1230          * a full request, and need to wait for more data from the client
1231          */
1232         while (out->data_sent_length < out->rdata.length) {
1233                 ok = create_next_pdu(ncacn_conn->p);
1234                 if (!ok) {
1235                         DEBUG(3, ("Failed to create next PDU!\n"));
1236                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
1237                         goto fail;
1238                 }
1239
1240                 ncacn_conn->iov = talloc_realloc(ncacn_conn,
1241                                                  ncacn_conn->iov,
1242                                                  struct iovec,
1243                                                  ncacn_conn->count + 1);
1244                 if (ncacn_conn->iov == NULL) {
1245                         DEBUG(3, ("Out of memory!\n"));
1246                         status = NT_STATUS_NO_MEMORY;
1247                         goto fail;
1248                 }
1249
1250                 ncacn_conn->iov[ncacn_conn->count].iov_base = out->frag.data;
1251                 ncacn_conn->iov[ncacn_conn->count].iov_len = out->frag.length;
1252
1253                 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
1254                            (unsigned int) ncacn_conn->count,
1255                            (unsigned int) ncacn_conn->iov[ncacn_conn->count].iov_len));
1256                 dump_data(11, (const uint8_t *) ncacn_conn->iov[ncacn_conn->count].iov_base,
1257                               ncacn_conn->iov[ncacn_conn->count].iov_len);
1258                 ncacn_conn->count++;
1259         }
1260
1261         /*
1262          * We still don't have a complete request, go back and wait for more
1263          * data.
1264          */
1265         if (ncacn_conn->count == 0) {
1266                 /* Wait for the next packet */
1267                 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1268                                                        ncacn_conn->ev_ctx,
1269                                                        ncacn_conn->tstream);
1270                 if (subreq == NULL) {
1271                         DEBUG(2, ("Failed to start receving packets\n"));
1272                         status = NT_STATUS_NO_MEMORY;
1273                         goto fail;
1274                 }
1275                 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1276                 return;
1277         }
1278
1279         DEBUG(10, ("Sending a total of %u bytes\n",
1280                    (unsigned int)ncacn_conn->p->out_data.data_sent_length));
1281
1282         subreq = tstream_writev_queue_send(ncacn_conn,
1283                                            ncacn_conn->ev_ctx,
1284                                            ncacn_conn->tstream,
1285                                            ncacn_conn->send_queue,
1286                                            ncacn_conn->iov,
1287                                            ncacn_conn->count);
1288         if (subreq == NULL) {
1289                 DEBUG(2, ("Failed to send packet\n"));
1290                 status = NT_STATUS_NO_MEMORY;
1291                 goto fail;
1292         }
1293
1294         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_done, ncacn_conn);
1295         return;
1296
1297 fail:
1298         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1299                   ncacn_conn->client_name, nt_errstr(status)));
1300
1301         /* Terminate client connection */
1302         talloc_free(ncacn_conn);
1303         return;
1304 }
1305
1306 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq)
1307 {
1308         struct dcerpc_ncacn_conn *ncacn_conn =
1309                 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1310         NTSTATUS status = NT_STATUS_OK;
1311         int sys_errno;
1312         int rc;
1313
1314         rc = tstream_writev_queue_recv(subreq, &sys_errno);
1315         TALLOC_FREE(subreq);
1316         if (rc < 0) {
1317                 DEBUG(2, ("Writev failed!\n"));
1318                 status = map_nt_error_from_unix(sys_errno);
1319                 goto fail;
1320         }
1321
1322         /* clear out any data that may have been left around */
1323         ncacn_conn->count = 0;
1324         TALLOC_FREE(ncacn_conn->iov);
1325         data_blob_free(&ncacn_conn->p->in_data.data);
1326         data_blob_free(&ncacn_conn->p->out_data.frag);
1327         data_blob_free(&ncacn_conn->p->out_data.rdata);
1328
1329         talloc_free_children(ncacn_conn->p->mem_ctx);
1330
1331         /* Wait for the next packet */
1332         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1333                                                ncacn_conn->ev_ctx,
1334                                                ncacn_conn->tstream);
1335         if (subreq == NULL) {
1336                 DEBUG(2, ("Failed to start receving packets\n"));
1337                 status = NT_STATUS_NO_MEMORY;
1338                 goto fail;
1339         }
1340
1341         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1342         return;
1343
1344 fail:
1345         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1346                   ncacn_conn->client_name, nt_errstr(status)));
1347
1348         /* Terminate client connection */
1349         talloc_free(ncacn_conn);
1350         return;
1351 }
1352
1353 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */