s3-rpc_server: Add make_internal_rpc_pipe().
[samba.git] / source3 / rpc_server / srv_pipe_hnd.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1998,
5  *  Largely re-written : 2005
6  *  Copyright (C) Jeremy Allison                1998 - 2005
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 "fake_file.h"
24 #include "rpc_dce.h"
25 #include "ntdomain.h"
26 #include "rpc_server/rpc_ncacn_np.h"
27 #include "rpc_server/srv_pipe_hnd.h"
28 #include "rpc_server/srv_pipe.h"
29 #include "rpc_server/rpc_server.h"
30 #include "rpc_server/rpc_config.h"
31 #include "../lib/tsocket/tsocket.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "librpc/ndr/ndr_table.h"
34
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_RPC_SRV
37
38 /****************************************************************************
39  Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
40 ****************************************************************************/
41
42 static ssize_t fill_rpc_header(struct pipes_struct *p, const char *data, size_t data_to_copy)
43 {
44         size_t len_needed_to_complete_hdr =
45                 MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu.length);
46
47         DEBUG(10, ("fill_rpc_header: data_to_copy = %u, "
48                    "len_needed_to_complete_hdr = %u, "
49                    "receive_len = %u\n",
50                    (unsigned int)data_to_copy,
51                    (unsigned int)len_needed_to_complete_hdr,
52                    (unsigned int)p->in_data.pdu.length ));
53
54         if (p->in_data.pdu.data == NULL) {
55                 p->in_data.pdu.data = talloc_array(p, uint8_t, RPC_HEADER_LEN);
56         }
57         if (p->in_data.pdu.data == NULL) {
58                 DEBUG(0, ("talloc failed\n"));
59                 return -1;
60         }
61
62         memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
63                 data, len_needed_to_complete_hdr);
64         p->in_data.pdu.length += len_needed_to_complete_hdr;
65
66         return (ssize_t)len_needed_to_complete_hdr;
67 }
68
69 static bool get_pdu_size(struct pipes_struct *p)
70 {
71         uint16_t frag_len;
72         /* the fill_rpc_header() call insures we copy only
73          * RPC_HEADER_LEN bytes. If this doesn't match then
74          * somethign is very wrong and we can only abort */
75         if (p->in_data.pdu.length != RPC_HEADER_LEN) {
76                 DEBUG(0, ("Unexpected RPC Header size! "
77                           "got %d, expected %d)\n",
78                           (int)p->in_data.pdu.length,
79                           RPC_HEADER_LEN));
80                 set_incoming_fault(p);
81                 return false;
82         }
83
84         frag_len = dcerpc_get_frag_length(&p->in_data.pdu);
85
86         /* verify it is a reasonable value */
87         if ((frag_len < RPC_HEADER_LEN) ||
88             (frag_len > RPC_MAX_PDU_FRAG_LEN)) {
89                 DEBUG(0, ("Unexpected RPC Fragment size! (%d)\n",
90                           frag_len));
91                 set_incoming_fault(p);
92                 return false;
93         }
94
95         p->in_data.pdu_needed_len = frag_len - RPC_HEADER_LEN;
96
97         /* allocate the space needed to fill the pdu */
98         p->in_data.pdu.data = talloc_realloc(p, p->in_data.pdu.data,
99                                                 uint8_t, frag_len);
100         if (p->in_data.pdu.data == NULL) {
101                 DEBUG(0, ("talloc_realloc failed\n"));
102                 set_incoming_fault(p);
103                 return false;
104         }
105
106         return true;
107 }
108
109 /****************************************************************************
110   Call this to free any talloc'ed memory. Do this after processing
111   a complete incoming and outgoing request (multiple incoming/outgoing
112   PDU's).
113 ****************************************************************************/
114
115 static void free_pipe_context(struct pipes_struct *p)
116 {
117         data_blob_free(&p->out_data.frag);
118         data_blob_free(&p->out_data.rdata);
119         data_blob_free(&p->in_data.data);
120
121         DEBUG(3, ("free_pipe_context: "
122                 "destroying talloc pool of size %lu\n",
123                 (unsigned long)talloc_total_size(p->mem_ctx)));
124         talloc_free_children(p->mem_ctx);
125 }
126
127 /****************************************************************************
128  Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
129 ****************************************************************************/
130
131 ssize_t process_incoming_data(struct pipes_struct *p, const char *data, size_t n)
132 {
133         size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN
134                                         - p->in_data.pdu.length);
135
136         DEBUG(10, ("process_incoming_data: Start: pdu.length = %u, "
137                    "pdu_needed_len = %u, incoming data = %u\n",
138                    (unsigned int)p->in_data.pdu.length,
139                    (unsigned int)p->in_data.pdu_needed_len,
140                    (unsigned int)n ));
141
142         if(data_to_copy == 0) {
143                 /*
144                  * This is an error - data is being received and there is no
145                  * space in the PDU. Free the received data and go into the
146                  * fault state.
147                  */
148                 DEBUG(0, ("process_incoming_data: "
149                           "No space in incoming pdu buffer. "
150                           "Current size = %u incoming data size = %u\n",
151                           (unsigned int)p->in_data.pdu.length,
152                           (unsigned int)n));
153                 set_incoming_fault(p);
154                 return -1;
155         }
156
157         /*
158          * If we have no data already, wait until we get at least
159          * a RPC_HEADER_LEN * number of bytes before we can do anything.
160          */
161
162         if ((p->in_data.pdu_needed_len == 0) &&
163             (p->in_data.pdu.length < RPC_HEADER_LEN)) {
164                 /*
165                  * Always return here. If we have more data then the RPC_HEADER
166                  * will be processed the next time around the loop.
167                  */
168                 return fill_rpc_header(p, data, data_to_copy);
169         }
170
171         /*
172          * At this point we know we have at least an RPC_HEADER_LEN amount of
173          * data stored in p->in_data.pdu.
174          */
175
176         /*
177          * If pdu_needed_len is zero this is a new pdu.
178          * Check how much more data we need, then loop again.
179          */
180         if (p->in_data.pdu_needed_len == 0) {
181
182                 bool ok = get_pdu_size(p);
183                 if (!ok) {
184                         return -1;
185                 }
186                 if (p->in_data.pdu_needed_len > 0) {
187                         return 0;
188                 }
189
190                 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU
191                  * that consists of an RPC_HEADER only. This is a
192                  * DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or
193                  * DCERPC_PKT_ORPHANED pdu type.
194                  * Deal with this in process_complete_pdu(). */
195         }
196
197         /*
198          * Ok - at this point we have a valid RPC_HEADER.
199          * Keep reading until we have a full pdu.
200          */
201
202         data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
203
204         /*
205          * Copy as much of the data as we need into the p->in_data.pdu buffer.
206          * pdu_needed_len becomes zero when we have a complete pdu.
207          */
208
209         memcpy((char *)&p->in_data.pdu.data[p->in_data.pdu.length],
210                 data, data_to_copy);
211         p->in_data.pdu.length += data_to_copy;
212         p->in_data.pdu_needed_len -= data_to_copy;
213
214         /*
215          * Do we have a complete PDU ?
216          * (return the number of bytes handled in the call)
217          */
218
219         if(p->in_data.pdu_needed_len == 0) {
220                 process_complete_pdu(p);
221                 return data_to_copy;
222         }
223
224         DEBUG(10, ("process_incoming_data: not a complete PDU yet. "
225                    "pdu.length = %u, pdu_needed_len = %u\n",
226                    (unsigned int)p->in_data.pdu.length,
227                    (unsigned int)p->in_data.pdu_needed_len));
228
229         return (ssize_t)data_to_copy;
230 }
231
232 /****************************************************************************
233  Accepts incoming data on an internal rpc pipe.
234 ****************************************************************************/
235
236 static ssize_t write_to_internal_pipe(struct pipes_struct *p, const char *data, size_t n)
237 {
238         size_t data_left = n;
239
240         while(data_left) {
241                 ssize_t data_used;
242
243                 DEBUG(10, ("write_to_pipe: data_left = %u\n",
244                           (unsigned int)data_left));
245
246                 data_used = process_incoming_data(p, data, data_left);
247
248                 DEBUG(10, ("write_to_pipe: data_used = %d\n",
249                            (int)data_used));
250
251                 if(data_used < 0) {
252                         return -1;
253                 }
254
255                 data_left -= data_used;
256                 data += data_used;
257         }
258
259         return n;
260 }
261
262 /****************************************************************************
263  Replies to a request to read data from a pipe.
264
265  Headers are interspersed with the data at PDU intervals. By the time
266  this function is called, the start of the data could possibly have been
267  read by an SMBtrans (file_offset != 0).
268
269  Calling create_rpc_reply() here is a hack. The data should already
270  have been prepared into arrays of headers + data stream sections.
271 ****************************************************************************/
272
273 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
274                                        size_t n, bool *is_data_outstanding)
275 {
276         uint32 pdu_remaining = 0;
277         ssize_t data_returned = 0;
278
279         if (!p) {
280                 DEBUG(0,("read_from_pipe: pipe not open\n"));
281                 return -1;
282         }
283
284         DEBUG(6,(" name: %s len: %u\n",
285                  ndr_interface_name(&p->contexts->syntax.uuid,
286                                     p->contexts->syntax.if_version),
287                  (unsigned int)n));
288
289         /*
290          * We cannot return more than one PDU length per
291          * read request.
292          */
293
294         /*
295          * This condition should result in the connection being closed.
296          * Netapp filers seem to set it to 0xffff which results in domain
297          * authentications failing.  Just ignore it so things work.
298          */
299
300         if(n > RPC_MAX_PDU_FRAG_LEN) {
301                 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
302                          "pipe %s. We can only service %d sized reads.\n",
303                          (unsigned int)n,
304                          ndr_interface_name(&p->contexts->syntax.uuid,
305                                             p->contexts->syntax.if_version),
306                          RPC_MAX_PDU_FRAG_LEN ));
307                 n = RPC_MAX_PDU_FRAG_LEN;
308         }
309
310         /*
311          * Determine if there is still data to send in the
312          * pipe PDU buffer. Always send this first. Never
313          * send more than is left in the current PDU. The
314          * client should send a new read request for a new
315          * PDU.
316          */
317
318         pdu_remaining = p->out_data.frag.length
319                 - p->out_data.current_pdu_sent;
320
321         if (pdu_remaining > 0) {
322                 data_returned = (ssize_t)MIN(n, pdu_remaining);
323
324                 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
325                           "current_pdu_sent = %u returning %d bytes.\n",
326                           ndr_interface_name(&p->contexts->syntax.uuid,
327                                              p->contexts->syntax.if_version),
328                           (unsigned int)p->out_data.frag.length,
329                           (unsigned int)p->out_data.current_pdu_sent,
330                           (int)data_returned));
331
332                 memcpy(data,
333                        p->out_data.frag.data
334                        + p->out_data.current_pdu_sent,
335                        data_returned);
336
337                 p->out_data.current_pdu_sent += (uint32)data_returned;
338                 goto out;
339         }
340
341         /*
342          * At this point p->current_pdu_len == p->current_pdu_sent (which
343          * may of course be zero if this is the first return fragment.
344          */
345
346         DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
347                   "= %u, p->out_data.rdata.length = %u.\n",
348                   ndr_interface_name(&p->contexts->syntax.uuid,
349                                      p->contexts->syntax.if_version),
350                   (int)p->fault_state,
351                   (unsigned int)p->out_data.data_sent_length,
352                   (unsigned int)p->out_data.rdata.length));
353
354         if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
355                 /*
356                  * We have sent all possible data, return 0.
357                  */
358                 data_returned = 0;
359                 goto out;
360         }
361
362         /*
363          * We need to create a new PDU from the data left in p->rdata.
364          * Create the header/data/footers. This also sets up the fields
365          * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
366          * and stores the outgoing PDU in p->current_pdu.
367          */
368
369         if(!create_next_pdu(p)) {
370                 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
371                          ndr_interface_name(&p->contexts->syntax.uuid,
372                                             p->contexts->syntax.if_version)));
373                 return -1;
374         }
375
376         data_returned = MIN(n, p->out_data.frag.length);
377
378         memcpy(data, p->out_data.frag.data, (size_t)data_returned);
379         p->out_data.current_pdu_sent += (uint32)data_returned;
380
381   out:
382         (*is_data_outstanding) = p->out_data.frag.length > n;
383
384         if (p->out_data.current_pdu_sent == p->out_data.frag.length) {
385                 /* We've returned everything in the out_data.frag
386                  * so we're done with this pdu. Free it and reset
387                  * current_pdu_sent. */
388                 p->out_data.current_pdu_sent = 0;
389                 data_blob_free(&p->out_data.frag);
390
391                 if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
392                         /*
393                          * We're completely finished with both outgoing and
394                          * incoming data streams. It's safe to free all
395                          * temporary data from this request.
396                          */
397                         free_pipe_context(p);
398                 }
399         }
400
401         return data_returned;
402 }
403
404 bool fsp_is_np(struct files_struct *fsp)
405 {
406         enum FAKE_FILE_TYPE type;
407
408         if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
409                 return false;
410         }
411
412         type = fsp->fake_file_handle->type;
413
414         return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
415                 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
416 }
417
418 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
419                  const struct tsocket_address *local_address,
420                  const struct tsocket_address *remote_address,
421                  struct auth_session_info *session_info,
422                  struct messaging_context *msg_ctx,
423                  struct fake_file_handle **phandle)
424 {
425         enum rpc_service_mode_e pipe_mode;
426         const char **proxy_list;
427         struct fake_file_handle *handle;
428         struct ndr_syntax_id syntax;
429
430         proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
431
432         handle = talloc(mem_ctx, struct fake_file_handle);
433         if (handle == NULL) {
434                 return NT_STATUS_NO_MEMORY;
435         }
436
437         /* Check what is the server type for this pipe.
438            Defaults to "embedded" */
439         pipe_mode = rpc_service_mode(name);
440
441         /* Still support the old method for defining external servers */
442         if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
443                 pipe_mode = RPC_SERVICE_MODE_EXTERNAL;
444         }
445
446         switch (pipe_mode) {
447         case RPC_SERVICE_MODE_EXTERNAL:
448
449                 handle->private_data = (void *)make_external_rpc_pipe_p(
450                                              handle, name,
451                                              local_address,
452                                              remote_address,
453                                              session_info);
454
455                 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
456                 break;
457
458         case RPC_SERVICE_MODE_EMBEDDED:
459
460                 if (!is_known_pipename(name, &syntax)) {
461                         TALLOC_FREE(handle);
462                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
463                 }
464
465                 handle->private_data = (void *)make_internal_rpc_pipe_p(
466                                              handle, &syntax, remote_address,
467                                              session_info, msg_ctx);
468
469                 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
470                 break;
471
472         case RPC_SERVICE_MODE_DISABLED:
473                 handle->private_data = NULL;
474                 break;
475         }
476
477         if (handle->private_data == NULL) {
478                 TALLOC_FREE(handle);
479                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
480         }
481
482         *phandle = handle;
483
484         return NT_STATUS_OK;
485 }
486
487 bool np_read_in_progress(struct fake_file_handle *handle)
488 {
489         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
490                 return false;
491         }
492
493         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
494                 struct np_proxy_state *p = talloc_get_type_abort(
495                         handle->private_data, struct np_proxy_state);
496                 size_t read_count;
497
498                 read_count = tevent_queue_length(p->read_queue);
499                 if (read_count > 0) {
500                         return true;
501                 }
502
503                 return false;
504         }
505
506         return false;
507 }
508
509 struct np_write_state {
510         struct tevent_context *ev;
511         struct np_proxy_state *p;
512         struct iovec iov;
513         ssize_t nwritten;
514 };
515
516 static void np_write_done(struct tevent_req *subreq);
517
518 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
519                                  struct fake_file_handle *handle,
520                                  const uint8_t *data, size_t len)
521 {
522         struct tevent_req *req;
523         struct np_write_state *state;
524         NTSTATUS status;
525
526         DEBUG(6, ("np_write_send: len: %d\n", (int)len));
527         dump_data(50, data, len);
528
529         req = tevent_req_create(mem_ctx, &state, struct np_write_state);
530         if (req == NULL) {
531                 return NULL;
532         }
533
534         if (len == 0) {
535                 state->nwritten = 0;
536                 status = NT_STATUS_OK;
537                 goto post_status;
538         }
539
540         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
541                 struct pipes_struct *p = talloc_get_type_abort(
542                         handle->private_data, struct pipes_struct);
543
544                 state->nwritten = write_to_internal_pipe(p, (const char *)data, len);
545
546                 status = (state->nwritten >= 0)
547                         ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
548                 goto post_status;
549         }
550
551         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
552                 struct np_proxy_state *p = talloc_get_type_abort(
553                         handle->private_data, struct np_proxy_state);
554                 struct tevent_req *subreq;
555
556                 state->ev = ev;
557                 state->p = p;
558                 state->iov.iov_base = discard_const_p(void, data);
559                 state->iov.iov_len = len;
560
561                 subreq = tstream_writev_queue_send(state, ev,
562                                                    p->npipe,
563                                                    p->write_queue,
564                                                    &state->iov, 1);
565                 if (subreq == NULL) {
566                         goto fail;
567                 }
568                 tevent_req_set_callback(subreq, np_write_done, req);
569                 return req;
570         }
571
572         status = NT_STATUS_INVALID_HANDLE;
573  post_status:
574         if (NT_STATUS_IS_OK(status)) {
575                 tevent_req_done(req);
576         } else {
577                 tevent_req_nterror(req, status);
578         }
579         return tevent_req_post(req, ev);
580  fail:
581         TALLOC_FREE(req);
582         return NULL;
583 }
584
585 static void np_write_done(struct tevent_req *subreq)
586 {
587         struct tevent_req *req = tevent_req_callback_data(
588                 subreq, struct tevent_req);
589         struct np_write_state *state = tevent_req_data(
590                 req, struct np_write_state);
591         ssize_t received;
592         int err;
593
594         received = tstream_writev_queue_recv(subreq, &err);
595         if (received < 0) {
596                 tevent_req_nterror(req, map_nt_error_from_unix(err));
597                 return;
598         }
599         state->nwritten = received;
600         tevent_req_done(req);
601 }
602
603 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
604 {
605         struct np_write_state *state = tevent_req_data(
606                 req, struct np_write_state);
607         NTSTATUS status;
608
609         if (tevent_req_is_nterror(req, &status)) {
610                 return status;
611         }
612         *pnwritten = state->nwritten;
613         return NT_STATUS_OK;
614 }
615
616 struct np_ipc_readv_next_vector_state {
617         uint8_t *buf;
618         size_t len;
619         off_t ofs;
620         size_t remaining;
621 };
622
623 static void np_ipc_readv_next_vector_init(struct np_ipc_readv_next_vector_state *s,
624                                           uint8_t *buf, size_t len)
625 {
626         ZERO_STRUCTP(s);
627
628         s->buf = buf;
629         s->len = MIN(len, UINT16_MAX);
630 }
631
632 static int np_ipc_readv_next_vector(struct tstream_context *stream,
633                                     void *private_data,
634                                     TALLOC_CTX *mem_ctx,
635                                     struct iovec **_vector,
636                                     size_t *count)
637 {
638         struct np_ipc_readv_next_vector_state *state =
639                 (struct np_ipc_readv_next_vector_state *)private_data;
640         struct iovec *vector;
641         ssize_t pending;
642         size_t wanted;
643
644         if (state->ofs == state->len) {
645                 *_vector = NULL;
646                 *count = 0;
647                 return 0;
648         }
649
650         pending = tstream_pending_bytes(stream);
651         if (pending == -1) {
652                 return -1;
653         }
654
655         if (pending == 0 && state->ofs != 0) {
656                 /* return a short read */
657                 *_vector = NULL;
658                 *count = 0;
659                 return 0;
660         }
661
662         if (pending == 0) {
663                 /* we want at least one byte and recheck again */
664                 wanted = 1;
665         } else {
666                 size_t missing = state->len - state->ofs;
667                 if (pending > missing) {
668                         /* there's more available */
669                         state->remaining = pending - missing;
670                         wanted = missing;
671                 } else {
672                         /* read what we can get and recheck in the next cycle */
673                         wanted = pending;
674                 }
675         }
676
677         vector = talloc_array(mem_ctx, struct iovec, 1);
678         if (!vector) {
679                 return -1;
680         }
681
682         vector[0].iov_base = state->buf + state->ofs;
683         vector[0].iov_len = wanted;
684
685         state->ofs += wanted;
686
687         *_vector = vector;
688         *count = 1;
689         return 0;
690 }
691
692 struct np_read_state {
693         struct np_proxy_state *p;
694         struct np_ipc_readv_next_vector_state next_vector;
695
696         ssize_t nread;
697         bool is_data_outstanding;
698 };
699
700 static void np_read_done(struct tevent_req *subreq);
701
702 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
703                                 struct fake_file_handle *handle,
704                                 uint8_t *data, size_t len)
705 {
706         struct tevent_req *req;
707         struct np_read_state *state;
708         NTSTATUS status;
709
710         req = tevent_req_create(mem_ctx, &state, struct np_read_state);
711         if (req == NULL) {
712                 return NULL;
713         }
714
715         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
716                 struct pipes_struct *p = talloc_get_type_abort(
717                         handle->private_data, struct pipes_struct);
718
719                 state->nread = read_from_internal_pipe(
720                         p, (char *)data, len, &state->is_data_outstanding);
721
722                 status = (state->nread >= 0)
723                         ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
724                 goto post_status;
725         }
726
727         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
728                 struct np_proxy_state *p = talloc_get_type_abort(
729                         handle->private_data, struct np_proxy_state);
730                 struct tevent_req *subreq;
731
732                 np_ipc_readv_next_vector_init(&state->next_vector,
733                                               data, len);
734
735                 subreq = tstream_readv_pdu_queue_send(state,
736                                                       ev,
737                                                       p->npipe,
738                                                       p->read_queue,
739                                                       np_ipc_readv_next_vector,
740                                                       &state->next_vector);
741                 if (subreq == NULL) {
742                         status = NT_STATUS_NO_MEMORY;
743                         goto post_status;
744                 }
745                 tevent_req_set_callback(subreq, np_read_done, req);
746                 return req;
747         }
748
749         status = NT_STATUS_INVALID_HANDLE;
750  post_status:
751         if (NT_STATUS_IS_OK(status)) {
752                 tevent_req_done(req);
753         } else {
754                 tevent_req_nterror(req, status);
755         }
756         return tevent_req_post(req, ev);
757 }
758
759 static void np_read_done(struct tevent_req *subreq)
760 {
761         struct tevent_req *req = tevent_req_callback_data(
762                 subreq, struct tevent_req);
763         struct np_read_state *state = tevent_req_data(
764                 req, struct np_read_state);
765         ssize_t ret;
766         int err;
767
768         ret = tstream_readv_pdu_queue_recv(subreq, &err);
769         TALLOC_FREE(subreq);
770         if (ret == -1) {
771                 tevent_req_nterror(req, map_nt_error_from_unix(err));
772                 return;
773         }
774
775         state->nread = ret;
776         state->is_data_outstanding = (state->next_vector.remaining > 0);
777
778         tevent_req_done(req);
779         return;
780 }
781
782 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
783                       bool *is_data_outstanding)
784 {
785         struct np_read_state *state = tevent_req_data(
786                 req, struct np_read_state);
787         NTSTATUS status;
788
789         if (tevent_req_is_nterror(req, &status)) {
790                 return status;
791         }
792
793         DEBUG(10, ("Received %d bytes. There is %smore data outstanding\n",
794                    (int)state->nread, state->is_data_outstanding?"":"no "));
795
796         *nread = state->nread;
797         *is_data_outstanding = state->is_data_outstanding;
798         return NT_STATUS_OK;
799 }