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