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