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