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