269b7014233b6f70cf5b9a3d9f6ed549f37be8e2
[mat/samba.git] / source3 / rpc_server / rpc_server.c
1 /*
2    Unix SMB/Netbios implementation.
3    Generic infrstructure for RPC Daemons
4    Copyright (C) Simo Sorce 2010
5    Copyright (C) Andrew Bartlett 2011
6    Copyright (C) Andreas Schneider 2011
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "rpc_server/rpc_pipes.h"
24 #include "rpc_server/rpc_server.h"
25 #include "rpc_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, &p->session_info);
127                 talloc_free(server_info);
128                 if (!NT_STATUS_IS_OK(status)) {
129                         DEBUG(1, ("Failed to init local auth token\n"));
130                         TALLOC_FREE(p);
131                         *perrno = EINVAL;
132                         return -1;
133                 }
134         }
135
136         *_p = p;
137         return 0;
138 }
139
140 /* Start listening on the appropriate unix socket and setup all is needed to
141  * dispatch requests to the pipes rpc implementation */
142
143 struct dcerpc_ncacn_listen_state {
144         struct ndr_syntax_id syntax_id;
145
146         int fd;
147         union {
148                 char *name;
149                 uint16_t port;
150         } ep;
151
152         struct tevent_context *ev_ctx;
153         struct messaging_context *msg_ctx;
154         dcerpc_ncacn_disconnect_fn disconnect_fn;
155 };
156
157 static void named_pipe_listener(struct tevent_context *ev,
158                                 struct tevent_fd *fde,
159                                 uint16_t flags,
160                                 void *private_data);
161
162 bool setup_named_pipe_socket(const char *pipe_name,
163                              struct tevent_context *ev_ctx,
164                              struct messaging_context *msg_ctx)
165 {
166         struct dcerpc_ncacn_listen_state *state;
167         struct tevent_fd *fde;
168         char *np_dir;
169
170         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
171         if (!state) {
172                 DEBUG(0, ("Out of memory\n"));
173                 return false;
174         }
175         state->ep.name = talloc_strdup(state, pipe_name);
176         if (state->ep.name == NULL) {
177                 DEBUG(0, ("Out of memory\n"));
178                 goto out;
179         }
180         state->fd = -1;
181
182         state->ev_ctx = ev_ctx;
183         state->msg_ctx = msg_ctx;
184
185         /*
186          * As lp_ncalrpc_dir() should have 0755, but
187          * lp_ncalrpc_dir()/np should have 0700, we need to
188          * create lp_ncalrpc_dir() first.
189          */
190         if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
191                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
192                           lp_ncalrpc_dir(), strerror(errno)));
193                 goto out;
194         }
195
196         np_dir = talloc_asprintf(state, "%s/np", lp_ncalrpc_dir());
197         if (!np_dir) {
198                 DEBUG(0, ("Out of memory\n"));
199                 goto out;
200         }
201
202         if (!directory_create_or_exist(np_dir, geteuid(), 0700)) {
203                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
204                           np_dir, strerror(errno)));
205                 goto out;
206         }
207
208         state->fd = create_pipe_sock(np_dir, pipe_name, 0700);
209         if (state->fd == -1) {
210                 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
211                           np_dir, pipe_name));
212                 goto out;
213         }
214         talloc_free(np_dir);
215
216         DEBUG(10, ("Openened pipe socket fd %d for %s\n",
217                    state->fd, pipe_name));
218
219         fde = tevent_add_fd(ev_ctx,
220                             state, state->fd, TEVENT_FD_READ,
221                             named_pipe_listener, state);
222         if (!fde) {
223                 DEBUG(0, ("Failed to add event handler!\n"));
224                 goto out;
225         }
226
227         tevent_fd_set_auto_close(fde);
228         return true;
229
230 out:
231         if (state->fd != -1) {
232                 close(state->fd);
233         }
234         TALLOC_FREE(state);
235         return false;
236 }
237
238 static void named_pipe_accept_function(struct tevent_context *ev_ctx,
239                                        struct messaging_context *msg_ctx,
240                                        const char *pipe_name,
241                                        int fd);
242
243 static void named_pipe_listener(struct tevent_context *ev,
244                                 struct tevent_fd *fde,
245                                 uint16_t flags,
246                                 void *private_data)
247 {
248         struct dcerpc_ncacn_listen_state *state =
249                         talloc_get_type_abort(private_data,
250                                               struct dcerpc_ncacn_listen_state);
251         struct sockaddr_un sunaddr;
252         socklen_t len;
253         int sd = -1;
254
255         /* TODO: should we have a limit to the number of clients ? */
256
257         len = sizeof(sunaddr);
258
259         sd = accept(state->fd,
260                     (struct sockaddr *)(void *)&sunaddr, &len);
261
262         if (sd == -1) {
263                 if (errno != EINTR) {
264                         DEBUG(6, ("Failed to get a valid socket [%s]\n",
265                                   strerror(errno)));
266                 }
267                 return;
268         }
269
270         DEBUG(6, ("Accepted socket %d\n", sd));
271
272         named_pipe_accept_function(state->ev_ctx,
273                                    state->msg_ctx,
274                                    state->ep.name,
275                                    sd);
276 }
277
278
279 /* This is the core of the rpc server.
280  * Accepts connections from clients and process requests using the appropriate
281  * dispatcher table. */
282
283 struct named_pipe_client {
284         const char *pipe_name;
285
286         struct tevent_context *ev;
287         struct messaging_context *msg_ctx;
288
289         uint16_t file_type;
290         uint16_t device_state;
291         uint64_t allocation_size;
292
293         struct tstream_context *tstream;
294
295         struct tsocket_address *client;
296         char *client_name;
297         struct tsocket_address *server;
298         char *server_name;
299
300         struct auth_session_info *session_info;
301
302         struct pipes_struct *p;
303
304         struct tevent_queue *write_queue;
305
306         struct iovec *iov;
307         size_t count;
308 };
309
310 static void named_pipe_accept_done(struct tevent_req *subreq);
311
312 static void named_pipe_accept_function(struct tevent_context *ev_ctx,
313                                        struct messaging_context *msg_ctx,
314                                        const char *pipe_name,
315                                        int fd)
316 {
317         struct named_pipe_client *npc;
318         struct tstream_context *plain;
319         struct tevent_req *subreq;
320         int ret;
321
322         npc = talloc_zero(NULL, struct named_pipe_client);
323         if (!npc) {
324                 DEBUG(0, ("Out of memory!\n"));
325                 close(fd);
326                 return;
327         }
328
329         npc->pipe_name = talloc_strdup(npc, pipe_name);
330         if (npc->pipe_name == NULL) {
331                 DEBUG(0, ("Out of memory!\n"));
332                 TALLOC_FREE(npc);
333                 close(fd);
334                 return;
335         }
336         npc->ev = ev_ctx;
337         npc->msg_ctx = msg_ctx;
338
339         /* make sure socket is in NON blocking state */
340         ret = set_blocking(fd, false);
341         if (ret != 0) {
342                 DEBUG(2, ("Failed to make socket non-blocking\n"));
343                 TALLOC_FREE(npc);
344                 close(fd);
345                 return;
346         }
347
348         ret = tstream_bsd_existing_socket(npc, fd, &plain);
349         if (ret != 0) {
350                 DEBUG(2, ("Failed to create tstream socket\n"));
351                 TALLOC_FREE(npc);
352                 close(fd);
353                 return;
354         }
355
356         npc->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
357         npc->device_state = 0xff | 0x0400 | 0x0100;
358         npc->allocation_size = 4096;
359
360         subreq = tstream_npa_accept_existing_send(npc, npc->ev, plain,
361                                                   npc->file_type,
362                                                   npc->device_state,
363                                                   npc->allocation_size);
364         if (!subreq) {
365                 DEBUG(2, ("Failed to start async accept procedure\n"));
366                 TALLOC_FREE(npc);
367                 close(fd);
368                 return;
369         }
370         tevent_req_set_callback(subreq, named_pipe_accept_done, npc);
371 }
372
373 static void named_pipe_packet_process(struct tevent_req *subreq);
374 static void named_pipe_packet_done(struct tevent_req *subreq);
375
376 static void named_pipe_accept_done(struct tevent_req *subreq)
377 {
378         struct auth_session_info_transport *session_info_transport;
379         struct named_pipe_client *npc =
380                 tevent_req_callback_data(subreq, struct named_pipe_client);
381         int error;
382         int ret;
383
384         ret = tstream_npa_accept_existing_recv(subreq, &error, npc,
385                                                 &npc->tstream,
386                                                 &npc->client,
387                                                 &npc->client_name,
388                                                 &npc->server,
389                                                 &npc->server_name,
390                                                 &session_info_transport);
391
392         npc->session_info = talloc_move(npc, &session_info_transport->session_info);
393
394         TALLOC_FREE(subreq);
395         if (ret != 0) {
396                 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
397                           strerror(error)));
398                 TALLOC_FREE(npc);
399                 return;
400         }
401
402         ret = make_server_pipes_struct(npc,
403                                        npc->msg_ctx,
404                                        npc->pipe_name, NCACN_NP,
405                                         false, npc->server, npc->client, npc->session_info,
406                                         &npc->p, &error);
407         if (ret != 0) {
408                 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
409                           strerror(error)));
410                 goto fail;
411         }
412
413         npc->write_queue = tevent_queue_create(npc, "np_server_write_queue");
414         if (!npc->write_queue) {
415                 DEBUG(2, ("Failed to set up write queue!\n"));
416                 goto fail;
417         }
418
419         /* And now start receiving and processing packets */
420         subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
421         if (!subreq) {
422                 DEBUG(2, ("Failed to start receving packets\n"));
423                 goto fail;
424         }
425         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
426         return;
427
428 fail:
429         DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
430                   npc->client_name));
431         /* terminate client connection */
432         talloc_free(npc);
433         return;
434 }
435
436 static void named_pipe_packet_process(struct tevent_req *subreq)
437 {
438         struct named_pipe_client *npc =
439                 tevent_req_callback_data(subreq, struct named_pipe_client);
440         struct _output_data *out = &npc->p->out_data;
441         DATA_BLOB recv_buffer = data_blob_null;
442         struct ncacn_packet *pkt;
443         NTSTATUS status;
444         ssize_t data_left;
445         ssize_t data_used;
446         char *data;
447         uint32_t to_send;
448         bool ok;
449
450         status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer);
451         TALLOC_FREE(subreq);
452         if (!NT_STATUS_IS_OK(status)) {
453                 goto fail;
454         }
455
456         data_left = recv_buffer.length;
457         data = (char *)recv_buffer.data;
458
459         while (data_left) {
460
461                 data_used = process_incoming_data(npc->p, data, data_left);
462                 if (data_used < 0) {
463                         DEBUG(3, ("Failed to process dceprc request!\n"));
464                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
465                         goto fail;
466                 }
467
468                 data_left -= data_used;
469                 data += data_used;
470         }
471
472         /* Do not leak this buffer, npc is a long lived context */
473         talloc_free(recv_buffer.data);
474         talloc_free(pkt);
475
476         /* this is needed because of the way DCERPC Binds work in
477          * the RPC marshalling code */
478         to_send = out->frag.length - out->current_pdu_sent;
479         if (to_send > 0) {
480
481                 DEBUG(10, ("Current_pdu_len = %u, "
482                            "current_pdu_sent = %u "
483                            "Returning %u bytes\n",
484                            (unsigned int)out->frag.length,
485                            (unsigned int)out->current_pdu_sent,
486                            (unsigned int)to_send));
487
488                 npc->iov = talloc_zero(npc, struct iovec);
489                 if (!npc->iov) {
490                         status = NT_STATUS_NO_MEMORY;
491                         goto fail;
492                 }
493                 npc->count = 1;
494
495                 npc->iov[0].iov_base = out->frag.data
496                                         + out->current_pdu_sent;
497                 npc->iov[0].iov_len = to_send;
498
499                 out->current_pdu_sent += to_send;
500         }
501
502         /* this condition is false for bind packets, or when we haven't
503          * yet got a full request, and need to wait for more data from
504          * the client */
505         while (out->data_sent_length < out->rdata.length) {
506
507                 ok = create_next_pdu(npc->p);
508                 if (!ok) {
509                         DEBUG(3, ("Failed to create next PDU!\n"));
510                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
511                         goto fail;
512                 }
513
514                 npc->iov = talloc_realloc(npc, npc->iov,
515                                             struct iovec, npc->count + 1);
516                 if (!npc->iov) {
517                         status = NT_STATUS_NO_MEMORY;
518                         goto fail;
519                 }
520
521                 npc->iov[npc->count].iov_base = out->frag.data;
522                 npc->iov[npc->count].iov_len = out->frag.length;
523
524                 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
525                            (unsigned int)npc->count,
526                            (unsigned int)npc->iov[npc->count].iov_len));
527                 dump_data(11, (const uint8_t *)npc->iov[npc->count].iov_base,
528                                 npc->iov[npc->count].iov_len);
529                 npc->count++;
530         }
531
532         /* we still don't have a complete request, go back and wait for more
533          * data */
534         if (npc->count == 0) {
535                 /* Wait for the next packet */
536                 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
537                 if (!subreq) {
538                         DEBUG(2, ("Failed to start receving packets\n"));
539                         status = NT_STATUS_NO_MEMORY;
540                         goto fail;
541                 }
542                 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
543                 return;
544         }
545
546         DEBUG(10, ("Sending a total of %u bytes\n",
547                    (unsigned int)npc->p->out_data.data_sent_length));
548
549         subreq = tstream_writev_queue_send(npc, npc->ev,
550                                            npc->tstream,
551                                            npc->write_queue,
552                                            npc->iov, npc->count);
553         if (!subreq) {
554                 DEBUG(2, ("Failed to send packet\n"));
555                 status = NT_STATUS_NO_MEMORY;
556                 goto fail;
557         }
558         tevent_req_set_callback(subreq, named_pipe_packet_done, npc);
559         return;
560
561 fail:
562         DEBUG(2, ("Fatal error(%s). "
563                   "Terminating client(%s) connection!\n",
564                   nt_errstr(status), npc->client_name));
565         /* terminate client connection */
566         talloc_free(npc);
567         return;
568 }
569
570 static void named_pipe_packet_done(struct tevent_req *subreq)
571 {
572         struct named_pipe_client *npc =
573                 tevent_req_callback_data(subreq, struct named_pipe_client);
574         int sys_errno;
575         int ret;
576
577         ret = tstream_writev_queue_recv(subreq, &sys_errno);
578         TALLOC_FREE(subreq);
579         if (ret == -1) {
580                 DEBUG(2, ("Writev failed!\n"));
581                 goto fail;
582         }
583
584         /* clear out any data that may have been left around */
585         npc->count = 0;
586         TALLOC_FREE(npc->iov);
587         data_blob_free(&npc->p->in_data.data);
588         data_blob_free(&npc->p->out_data.frag);
589         data_blob_free(&npc->p->out_data.rdata);
590
591         /* Wait for the next packet */
592         subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
593         if (!subreq) {
594                 DEBUG(2, ("Failed to start receving packets\n"));
595                 sys_errno = ENOMEM;
596                 goto fail;
597         }
598         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
599         return;
600
601 fail:
602         DEBUG(2, ("Fatal error(%s). "
603                   "Terminating client(%s) connection!\n",
604                   strerror(sys_errno), npc->client_name));
605         /* terminate client connection */
606         talloc_free(npc);
607         return;
608 }
609
610 static void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
611                                 struct messaging_context *msg_ctx,
612                                 enum dcerpc_transport_t transport,
613                                 const char *name,
614                                 struct tsocket_address *cli_addr,
615                                 struct tsocket_address *srv_addr,
616                                 int s,
617                                 dcerpc_ncacn_disconnect_fn fn);
618
619 /********************************************************************
620  * Start listening on the tcp/ip socket
621  ********************************************************************/
622
623 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
624                                         struct tevent_fd *fde,
625                                         uint16_t flags,
626                                         void *private_data);
627
628 uint16_t setup_dcerpc_ncacn_tcpip_socket(struct tevent_context *ev_ctx,
629                                          struct messaging_context *msg_ctx,
630                                          const struct sockaddr_storage *ifss,
631                                          uint16_t port)
632 {
633         struct dcerpc_ncacn_listen_state *state;
634         struct tevent_fd *fde;
635         int rc;
636
637         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
638         if (state == NULL) {
639                 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Out of memory\n"));
640                 return 0;
641         }
642
643         state->fd = -1;
644         state->ep.port = port;
645         state->disconnect_fn = NULL;
646
647         if (state->ep.port == 0) {
648                 uint16_t i;
649
650                 for (i = SERVER_TCP_LOW_PORT; i <= SERVER_TCP_HIGH_PORT; i++) {
651                         state->fd = open_socket_in(SOCK_STREAM,
652                                                    i,
653                                                    0,
654                                                    ifss,
655                                                    false);
656                         if (state->fd > 0) {
657                                 state->ep.port = i;
658                                 break;
659                         }
660                 }
661         } else {
662                 state->fd = open_socket_in(SOCK_STREAM,
663                                            state->ep.port,
664                                            0,
665                                            ifss,
666                                            true);
667         }
668         if (state->fd == -1) {
669                 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Failed to create "
670                           "socket on port %u!\n", state->ep.port));
671                 goto out;
672         }
673
674         state->ev_ctx = ev_ctx;
675         state->msg_ctx = msg_ctx;
676
677         /* ready to listen */
678         set_socket_options(state->fd, "SO_KEEPALIVE");
679         set_socket_options(state->fd, lp_socket_options());
680
681         /* Set server socket to non-blocking for the accept. */
682         set_blocking(state->fd, false);
683
684         rc = listen(state->fd, SMBD_LISTEN_BACKLOG);
685         if (rc == -1) {
686                 DEBUG(0,("setup_tcpip_socket: listen - %s\n", strerror(errno)));
687                 goto out;
688         }
689
690         DEBUG(10, ("setup_tcpip_socket: openened socket fd %d for port %u\n",
691                    state->fd, state->ep.port));
692
693         fde = tevent_add_fd(state->ev_ctx,
694                             state,
695                             state->fd,
696                             TEVENT_FD_READ,
697                             dcerpc_ncacn_tcpip_listener,
698                             state);
699         if (fde == NULL) {
700                 DEBUG(0, ("setup_tcpip_socket: Failed to add event handler!\n"));
701                 goto out;
702         }
703
704         tevent_fd_set_auto_close(fde);
705
706         return state->ep.port;
707 out:
708         if (state->fd != -1) {
709                 close(state->fd);
710         }
711         TALLOC_FREE(state);
712
713         return 0;
714 }
715
716 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
717                                         struct tevent_fd *fde,
718                                         uint16_t flags,
719                                         void *private_data)
720 {
721         struct dcerpc_ncacn_listen_state *state =
722                         talloc_get_type_abort(private_data,
723                                               struct dcerpc_ncacn_listen_state);
724         struct tsocket_address *cli_addr = NULL;
725         struct tsocket_address *srv_addr = NULL;
726         struct sockaddr_storage addr;
727         socklen_t in_addrlen = sizeof(addr);
728         int s = -1;
729         int rc;
730
731         s = accept(state->fd, (struct sockaddr *)(void *) &addr, &in_addrlen);
732         if (s == -1) {
733                 if (errno != EINTR) {
734                         DEBUG(0,("tcpip_listener accept: %s\n",
735                                  strerror(errno)));
736                 }
737                 return;
738         }
739
740         rc = tsocket_address_bsd_from_sockaddr(state,
741                                                (struct sockaddr *)(void *) &addr,
742                                                in_addrlen,
743                                                &cli_addr);
744         if (rc < 0) {
745                 close(s);
746                 return;
747         }
748
749         rc = getsockname(s, (struct sockaddr *)(void *) &addr, &in_addrlen);
750         if (rc < 0) {
751                 close(s);
752                 return;
753         }
754
755         rc = tsocket_address_bsd_from_sockaddr(state,
756                                                (struct sockaddr *)(void *) &addr,
757                                                in_addrlen,
758                                                &srv_addr);
759         if (rc < 0) {
760                 close(s);
761                 return;
762         }
763
764         DEBUG(6, ("tcpip_listener: Accepted socket %d\n", s));
765
766         dcerpc_ncacn_accept(state->ev_ctx,
767                             state->msg_ctx,
768                             NCACN_IP_TCP,
769                             NULL,
770                             cli_addr,
771                             srv_addr,
772                             s,
773                             NULL);
774 }
775
776 /********************************************************************
777  * Start listening on the ncalrpc socket
778  ********************************************************************/
779
780 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
781                                     struct tevent_fd *fde,
782                                     uint16_t flags,
783                                     void *private_data);
784
785 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
786                                  struct messaging_context *msg_ctx,
787                                  const char *name,
788                                  dcerpc_ncacn_disconnect_fn fn)
789 {
790         struct dcerpc_ncacn_listen_state *state;
791         struct tevent_fd *fde;
792
793         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
794         if (state == NULL) {
795                 DEBUG(0, ("Out of memory\n"));
796                 return false;
797         }
798
799         state->fd = -1;
800         state->disconnect_fn = fn;
801
802         if (name == NULL) {
803                 name = "DEFAULT";
804         }
805         state->ep.name = talloc_strdup(state, name);
806
807         if (state->ep.name == NULL) {
808                 DEBUG(0, ("Out of memory\n"));
809                 talloc_free(state);
810                 return false;
811         }
812
813         if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
814                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
815                           lp_ncalrpc_dir(), strerror(errno)));
816                 goto out;
817         }
818
819         state->fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
820         if (state->fd == -1) {
821                 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
822                           lp_ncalrpc_dir(), name));
823                 goto out;
824         }
825
826         DEBUG(10, ("Openened pipe socket fd %d for %s\n", state->fd, name));
827
828         state->ev_ctx = ev_ctx;
829         state->msg_ctx = msg_ctx;
830
831         /* Set server socket to non-blocking for the accept. */
832         set_blocking(state->fd, false);
833
834         fde = tevent_add_fd(state->ev_ctx,
835                             state,
836                             state->fd,
837                             TEVENT_FD_READ,
838                             dcerpc_ncalrpc_listener,
839                             state);
840         if (fde == NULL) {
841                 DEBUG(0, ("Failed to add event handler for ncalrpc!\n"));
842                 goto out;
843         }
844
845         tevent_fd_set_auto_close(fde);
846
847         return true;
848 out:
849         if (state->fd != -1) {
850                 close(state->fd);
851         }
852         TALLOC_FREE(state);
853
854         return 0;
855 }
856
857 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
858                                         struct tevent_fd *fde,
859                                         uint16_t flags,
860                                         void *private_data)
861 {
862         struct dcerpc_ncacn_listen_state *state =
863                         talloc_get_type_abort(private_data,
864                                               struct dcerpc_ncacn_listen_state);
865         struct tsocket_address *cli_addr = NULL;
866         struct sockaddr_un sunaddr;
867         struct sockaddr *addr = (struct sockaddr *)(void *)&sunaddr;
868         socklen_t len = sizeof(sunaddr);
869         int sd = -1;
870         int rc;
871
872         ZERO_STRUCT(sunaddr);
873
874         sd = accept(state->fd, addr, &len);
875         if (sd == -1) {
876                 if (errno != EINTR) {
877                         DEBUG(0, ("ncalrpc accept() failed: %s\n", strerror(errno)));
878                 }
879                 return;
880         }
881
882         rc = tsocket_address_bsd_from_sockaddr(state,
883                                                addr, len,
884                                                &cli_addr);
885         if (rc < 0) {
886                 close(sd);
887                 return;
888         }
889
890         DEBUG(10, ("Accepted ncalrpc socket %d\n", sd));
891
892         dcerpc_ncacn_accept(state->ev_ctx,
893                             state->msg_ctx,
894                             NCALRPC,
895                             state->ep.name,
896                             cli_addr, NULL, sd,
897                             state->disconnect_fn);
898 }
899
900 struct dcerpc_ncacn_conn {
901         enum dcerpc_transport_t transport;
902
903         int sock;
904
905         struct pipes_struct *p;
906         dcerpc_ncacn_disconnect_fn disconnect_fn;
907
908         struct tevent_context *ev_ctx;
909         struct messaging_context *msg_ctx;
910
911         struct tstream_context *tstream;
912         struct tevent_queue *send_queue;
913
914         struct tsocket_address *client;
915         char *client_name;
916         struct tsocket_address *server;
917         char *server_name;
918         struct auth_session_info *session_info;
919
920         struct iovec *iov;
921         size_t count;
922 };
923
924 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
925 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
926
927 static void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
928                                 struct messaging_context *msg_ctx,
929                                 enum dcerpc_transport_t transport,
930                                 const char *name,
931                                 struct tsocket_address *cli_addr,
932                                 struct tsocket_address *srv_addr,
933                                 int s,
934                                 dcerpc_ncacn_disconnect_fn fn) {
935         struct dcerpc_ncacn_conn *ncacn_conn;
936         struct tevent_req *subreq;
937         const char *cli_str;
938         const char *srv_str = NULL;
939         bool system_user = false;
940         char *pipe_name;
941         NTSTATUS status;
942         int sys_errno;
943         uid_t uid;
944         int rc;
945
946         DEBUG(10, ("dcerpc_ncacn_accept\n"));
947
948         ncacn_conn = talloc_zero(ev_ctx, struct dcerpc_ncacn_conn);
949         if (ncacn_conn == NULL) {
950                 DEBUG(0, ("Out of memory!\n"));
951                 close(s);
952                 return;
953         }
954
955         ncacn_conn->transport = transport;
956         ncacn_conn->ev_ctx = ev_ctx;
957         ncacn_conn->msg_ctx = msg_ctx;
958         ncacn_conn->sock = s;
959         ncacn_conn->disconnect_fn = fn;
960
961         ncacn_conn->client = talloc_move(ncacn_conn, &cli_addr);
962         if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
963                 ncacn_conn->client_name =
964                         tsocket_address_inet_addr_string(ncacn_conn->client,
965                                                          ncacn_conn);
966         } else {
967                 ncacn_conn->client_name =
968                         tsocket_address_unix_path(ncacn_conn->client,
969                                                   ncacn_conn);
970         }
971         if (ncacn_conn->client_name == NULL) {
972                 DEBUG(0, ("Out of memory!\n"));
973                 talloc_free(ncacn_conn);
974                 close(s);
975                 return;
976         }
977
978         if (srv_addr != NULL) {
979                 ncacn_conn->server = talloc_move(ncacn_conn, &srv_addr);
980
981                 ncacn_conn->server_name =
982                         tsocket_address_inet_addr_string(ncacn_conn->server,
983                                                          ncacn_conn);
984                 if (ncacn_conn->server_name == NULL) {
985                         DEBUG(0, ("Out of memory!\n"));
986                         talloc_free(ncacn_conn);
987                         close(s);
988                         return;
989                 }
990         }
991
992         switch (transport) {
993                 case NCACN_IP_TCP:
994                         pipe_name = tsocket_address_string(ncacn_conn->client,
995                                                            ncacn_conn);
996                         if (pipe_name == NULL) {
997                                 close(s);
998                                 talloc_free(ncacn_conn);
999                                 return;
1000                         }
1001
1002                         break;
1003                 case NCALRPC:
1004                         rc = sys_getpeereid(s, &uid);
1005                         if (rc < 0) {
1006                                 DEBUG(2, ("Failed to get ncalrpc connecting uid!"));
1007                         } else {
1008                                 if (uid == sec_initial_uid()) {
1009                                         system_user = true;
1010                                 }
1011                         }
1012                 case NCACN_NP:
1013                         pipe_name = talloc_strdup(ncacn_conn,
1014                                                   name);
1015                         if (pipe_name == NULL) {
1016                                 close(s);
1017                                 talloc_free(ncacn_conn);
1018                                 return;
1019                         }
1020                         break;
1021                 default:
1022                         DEBUG(0, ("unknown dcerpc transport: %u!\n",
1023                                   transport));
1024                         talloc_free(ncacn_conn);
1025                         close(s);
1026                         return;
1027         }
1028
1029         rc = set_blocking(s, false);
1030         if (rc < 0) {
1031                 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1032                 talloc_free(ncacn_conn);
1033                 close(s);
1034                 return;
1035         }
1036
1037         /*
1038          * As soon as we have tstream_bsd_existing_socket set up it will
1039          * take care of closing the socket.
1040          */
1041         rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream);
1042         if (rc < 0) {
1043                 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1044                 talloc_free(ncacn_conn);
1045                 close(s);
1046                 return;
1047         }
1048
1049         if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
1050                 cli_str = ncacn_conn->client_name;
1051         } else {
1052                 cli_str = "";
1053         }
1054
1055         if (ncacn_conn->server != NULL) {
1056                 if (tsocket_address_is_inet(ncacn_conn->server, "ip")) {
1057                         srv_str = ncacn_conn->server_name;
1058                 } else {
1059                         srv_str = NULL;
1060                 }
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         /* Wait for the next packet */
1293         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1294                                                ncacn_conn->ev_ctx,
1295                                                ncacn_conn->tstream);
1296         if (subreq == NULL) {
1297                 DEBUG(2, ("Failed to start receving packets\n"));
1298                 status = NT_STATUS_NO_MEMORY;
1299                 goto fail;
1300         }
1301
1302         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1303         return;
1304
1305 fail:
1306         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1307                   ncacn_conn->client_name, nt_errstr(status)));
1308
1309         /* Terminate client connection */
1310         talloc_free(ncacn_conn);
1311         return;
1312 }
1313
1314 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */