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