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