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