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