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