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