s3:rpc_server: make use of the npa_tstream code to connect to named pipes
[idra/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 "../librpc/gen_ndr/srv_spoolss.h"
24 #include "librpc/gen_ndr/ndr_named_pipe_auth.h"
25 #include "../libcli/named_pipe_auth/npa_tstream.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_SRV
29
30 static int pipes_open;
31
32 static pipes_struct *InternalPipes;
33
34 /* TODO
35  * the following prototypes are declared here to avoid
36  * code being moved about too much for a patch to be
37  * disrupted / less obvious.
38  *
39  * these functions, and associated functions that they
40  * call, should be moved behind a .so module-loading
41  * system _anyway_.  so that's the next step...
42  */
43
44 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p);
45
46 /****************************************************************************
47  Internal Pipe iterator functions.
48 ****************************************************************************/
49
50 pipes_struct *get_first_internal_pipe(void)
51 {
52         return InternalPipes;
53 }
54
55 pipes_struct *get_next_internal_pipe(pipes_struct *p)
56 {
57         return p->next;
58 }
59
60 /****************************************************************************
61  Initialise an outgoing packet.
62 ****************************************************************************/
63
64 static bool pipe_init_outgoing_data(pipes_struct *p)
65 {
66         output_data *o_data = &p->out_data;
67
68         /* Reset the offset counters. */
69         o_data->data_sent_length = 0;
70         o_data->current_pdu_sent = 0;
71
72         prs_mem_free(&o_data->frag);
73
74         /* Free any memory in the current return data buffer. */
75         prs_mem_free(&o_data->rdata);
76
77         /*
78          * Initialize the outgoing RPC data buffer.
79          * we will use this as the raw data area for replying to rpc requests.
80          */     
81         if(!prs_init(&o_data->rdata, 128, p->mem_ctx, MARSHALL)) {
82                 DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
83                 return False;
84         }
85
86         return True;
87 }
88
89 /****************************************************************************
90  Make an internal namedpipes structure
91 ****************************************************************************/
92
93 static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
94                                                      const struct ndr_syntax_id *syntax,
95                                                      const char *client_address,
96                                                      struct auth_serversupplied_info *server_info)
97 {
98         pipes_struct *p;
99
100         DEBUG(4,("Create pipe requested %s\n",
101                  get_pipe_name_from_syntax(talloc_tos(), syntax)));
102
103         p = TALLOC_ZERO_P(mem_ctx, struct pipes_struct);
104
105         if (!p) {
106                 DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
107                 return NULL;
108         }
109
110         p->mem_ctx = talloc_named(p, 0, "pipe %s %p",
111                                  get_pipe_name_from_syntax(talloc_tos(),
112                                                            syntax), p);
113         if (p->mem_ctx == NULL) {
114                 DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
115                 TALLOC_FREE(p);
116                 return NULL;
117         }
118
119         if (!init_pipe_handle_list(p, syntax)) {
120                 DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
121                 TALLOC_FREE(p);
122                 return NULL;
123         }
124
125         /*
126          * Initialize the incoming RPC data buffer with one PDU worth of memory.
127          * We cheat here and say we're marshalling, as we intend to add incoming
128          * data directly into the prs_struct and we want it to auto grow. We will
129          * change the type to UNMARSALLING before processing the stream.
130          */
131
132         if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
133                 DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
134                 close_policy_by_pipe(p);
135                 TALLOC_FREE(p);
136                 return NULL;
137         }
138
139         p->server_info = copy_serverinfo(p, server_info);
140         if (p->server_info == NULL) {
141                 DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
142                 close_policy_by_pipe(p);
143                 TALLOC_FREE(p);
144                 return NULL;
145         }
146
147         DLIST_ADD(InternalPipes, p);
148
149         memcpy(p->client_address, client_address, sizeof(p->client_address));
150
151         p->endian = RPC_LITTLE_ENDIAN;
152
153         /*
154          * Initialize the outgoing RPC data buffer with no memory.
155          */     
156         prs_init_empty(&p->out_data.rdata, p->mem_ctx, MARSHALL);
157
158         p->syntax = *syntax;
159
160         DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
161                  get_pipe_name_from_syntax(talloc_tos(), syntax), pipes_open));
162
163         talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
164
165         return p;
166 }
167
168 /****************************************************************************
169  Sets the fault state on incoming packets.
170 ****************************************************************************/
171
172 static void set_incoming_fault(pipes_struct *p)
173 {
174         prs_mem_free(&p->in_data.data);
175         p->in_data.pdu_needed_len = 0;
176         p->in_data.pdu_received_len = 0;
177         p->fault_state = True;
178         DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
179                    get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
180 }
181
182 /****************************************************************************
183  Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
184 ****************************************************************************/
185
186 static ssize_t fill_rpc_header(pipes_struct *p, char *data, size_t data_to_copy)
187 {
188         size_t len_needed_to_complete_hdr = MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu_received_len);
189
190         DEBUG(10,("fill_rpc_header: data_to_copy = %u, len_needed_to_complete_hdr = %u, receive_len = %u\n",
191                         (unsigned int)data_to_copy, (unsigned int)len_needed_to_complete_hdr,
192                         (unsigned int)p->in_data.pdu_received_len ));
193
194         if (p->in_data.current_in_pdu == NULL) {
195                 p->in_data.current_in_pdu = talloc_array(p, uint8_t,
196                                                          RPC_HEADER_LEN);
197         }
198         if (p->in_data.current_in_pdu == NULL) {
199                 DEBUG(0, ("talloc failed\n"));
200                 return -1;
201         }
202
203         memcpy((char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, len_needed_to_complete_hdr);
204         p->in_data.pdu_received_len += len_needed_to_complete_hdr;
205
206         return (ssize_t)len_needed_to_complete_hdr;
207 }
208
209 /****************************************************************************
210  Unmarshalls a new PDU header. Assumes the raw header data is in current_in_pdu.
211 ****************************************************************************/
212
213 static ssize_t unmarshall_rpc_header(pipes_struct *p)
214 {
215         /*
216          * Unmarshall the header to determine the needed length.
217          */
218
219         prs_struct rpc_in;
220
221         if(p->in_data.pdu_received_len != RPC_HEADER_LEN) {
222                 DEBUG(0,("unmarshall_rpc_header: assert on rpc header length failed.\n"));
223                 set_incoming_fault(p);
224                 return -1;
225         }
226
227         prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
228         prs_set_endian_data( &rpc_in, p->endian);
229
230         prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
231                                         p->in_data.pdu_received_len, False);
232
233         /*
234          * Unmarshall the header as this will tell us how much
235          * data we need to read to get the complete pdu.
236          * This also sets the endian flag in rpc_in.
237          */
238
239         if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
240                 DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
241                 set_incoming_fault(p);
242                 prs_mem_free(&rpc_in);
243                 return -1;
244         }
245
246         /*
247          * Validate the RPC header.
248          */
249
250         if(p->hdr.major != 5 && p->hdr.minor != 0) {
251                 DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
252                 set_incoming_fault(p);
253                 prs_mem_free(&rpc_in);
254                 return -1;
255         }
256
257         /*
258          * If there's not data in the incoming buffer this should be the start of a new RPC.
259          */
260
261         if(prs_offset(&p->in_data.data) == 0) {
262
263                 /*
264                  * AS/U doesn't set FIRST flag in a BIND packet it seems.
265                  */
266
267                 if ((p->hdr.pkt_type == DCERPC_PKT_REQUEST) && !(p->hdr.flags & DCERPC_PFC_FLAG_FIRST)) {
268                         /*
269                          * Ensure that the FIRST flag is set. If not then we have
270                          * a stream missmatch.
271                          */
272
273                         DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
274                         set_incoming_fault(p);
275                         prs_mem_free(&rpc_in);
276                         return -1;
277                 }
278
279                 /*
280                  * If this is the first PDU then set the endianness
281                  * flag in the pipe. We will need this when parsing all
282                  * data in this RPC.
283                  */
284
285                 p->endian = rpc_in.bigendian_data;
286
287                 DEBUG(5,("unmarshall_rpc_header: using %sendian RPC\n",
288                                 p->endian == RPC_LITTLE_ENDIAN ? "little-" : "big-" ));
289
290         } else {
291
292                 /*
293                  * If this is *NOT* the first PDU then check the endianness
294                  * flag in the pipe is the same as that in the PDU.
295                  */
296
297                 if (p->endian != rpc_in.bigendian_data) {
298                         DEBUG(0,("unmarshall_rpc_header: FIRST endianness flag (%d) different in next PDU !\n", (int)p->endian));
299                         set_incoming_fault(p);
300                         prs_mem_free(&rpc_in);
301                         return -1;
302                 }
303         }
304
305         /*
306          * Ensure that the pdu length is sane.
307          */
308
309         if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > RPC_MAX_PDU_FRAG_LEN)) {
310                 DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
311                 set_incoming_fault(p);
312                 prs_mem_free(&rpc_in);
313                 return -1;
314         }
315
316         DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
317                         (unsigned int)p->hdr.flags ));
318
319         p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;
320
321         prs_mem_free(&rpc_in);
322
323         p->in_data.current_in_pdu = TALLOC_REALLOC_ARRAY(
324                 p, p->in_data.current_in_pdu, uint8_t, p->hdr.frag_len);
325         if (p->in_data.current_in_pdu == NULL) {
326                 DEBUG(0, ("talloc failed\n"));
327                 set_incoming_fault(p);
328                 return -1;
329         }
330
331         return 0; /* No extra data processed. */
332 }
333
334 /****************************************************************************
335  Call this to free any talloc'ed memory. Do this before and after processing
336  a complete PDU.
337 ****************************************************************************/
338
339 static void free_pipe_context(pipes_struct *p)
340 {
341         if (p->mem_ctx) {
342                 DEBUG(3,("free_pipe_context: destroying talloc pool of size "
343                          "%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
344                 talloc_free_children(p->mem_ctx);
345         } else {
346                 p->mem_ctx = talloc_named(p, 0, "pipe %s %p",
347                                     get_pipe_name_from_syntax(talloc_tos(),
348                                                               &p->syntax), p);
349                 if (p->mem_ctx == NULL) {
350                         p->fault_state = True;
351                 }
352         }
353 }
354
355 /****************************************************************************
356  Processes a request pdu. This will do auth processing if needed, and
357  appends the data into the complete stream if the LAST flag is not set.
358 ****************************************************************************/
359
360 static bool process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
361 {
362         uint32 ss_padding_len = 0;
363         size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
364                                 (p->hdr.auth_len ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len;
365
366         if(!p->pipe_bound) {
367                 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
368                 set_incoming_fault(p);
369                 return False;
370         }
371
372         /*
373          * Check if we need to do authentication processing.
374          * This is only done on requests, not binds.
375          */
376
377         /*
378          * Read the RPC request header.
379          */
380
381         if(!smb_io_rpc_hdr_req("req", &p->hdr_req, rpc_in_p, 0)) {
382                 DEBUG(0,("process_request_pdu: failed to unmarshall RPC_HDR_REQ.\n"));
383                 set_incoming_fault(p);
384                 return False;
385         }
386
387         switch(p->auth.auth_type) {
388                 case PIPE_AUTH_TYPE_NONE:
389                         break;
390
391                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
392                 case PIPE_AUTH_TYPE_NTLMSSP:
393                 {
394                         NTSTATUS status;
395                         if(!api_pipe_ntlmssp_auth_process(p, rpc_in_p, &ss_padding_len, &status)) {
396                                 DEBUG(0,("process_request_pdu: failed to do auth processing.\n"));
397                                 DEBUG(0,("process_request_pdu: error was %s.\n", nt_errstr(status) ));
398                                 set_incoming_fault(p);
399                                 return False;
400                         }
401                         break;
402                 }
403
404                 case PIPE_AUTH_TYPE_SCHANNEL:
405                         if (!api_pipe_schannel_process(p, rpc_in_p, &ss_padding_len)) {
406                                 DEBUG(3,("process_request_pdu: failed to do schannel processing.\n"));
407                                 set_incoming_fault(p);
408                                 return False;
409                         }
410                         break;
411
412                 default:
413                         DEBUG(0,("process_request_pdu: unknown auth type %u set.\n", (unsigned int)p->auth.auth_type ));
414                         set_incoming_fault(p);
415                         return False;
416         }
417
418         /* Now we've done the sign/seal we can remove any padding data. */
419         if (data_len > ss_padding_len) {
420                 data_len -= ss_padding_len;
421         }
422
423         /*
424          * Check the data length doesn't go over the 15Mb limit.
425          * increased after observing a bug in the Windows NT 4.0 SP6a
426          * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
427          * will not fit in the initial buffer of size 0x1068   --jerry 22/01/2002
428          */
429         
430         if(prs_offset(&p->in_data.data) + data_len > MAX_RPC_DATA_SIZE) {
431                 DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
432                                 (unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
433                 set_incoming_fault(p);
434                 return False;
435         }
436
437         /*
438          * Append the data portion into the buffer and return.
439          */
440
441         if(!prs_append_some_prs_data(&p->in_data.data, rpc_in_p, prs_offset(rpc_in_p), data_len)) {
442                 DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n",
443                                 (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) ));
444                 set_incoming_fault(p);
445                 return False;
446         }
447
448         if(p->hdr.flags & DCERPC_PFC_FLAG_LAST) {
449                 bool ret = False;
450                 /*
451                  * Ok - we finally have a complete RPC stream.
452                  * Call the rpc command to process it.
453                  */
454
455                 /*
456                  * Ensure the internal prs buffer size is *exactly* the same
457                  * size as the current offset.
458                  */
459
460                 if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) {
461                         DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n"));
462                         set_incoming_fault(p);
463                         return False;
464                 }
465
466                 /*
467                  * Set the parse offset to the start of the data and set the
468                  * prs_struct to UNMARSHALL.
469                  */
470
471                 prs_set_offset(&p->in_data.data, 0);
472                 prs_switch_type(&p->in_data.data, UNMARSHALL);
473
474                 /*
475                  * Process the complete data stream here.
476                  */
477
478                 free_pipe_context(p);
479
480                 if(pipe_init_outgoing_data(p)) {
481                         ret = api_pipe_request(p);
482                 }
483
484                 free_pipe_context(p);
485
486                 /*
487                  * We have consumed the whole data stream. Set back to
488                  * marshalling and set the offset back to the start of
489                  * the buffer to re-use it (we could also do a prs_mem_free()
490                  * and then re_init on the next start of PDU. Not sure which
491                  * is best here.... JRA.
492                  */
493
494                 prs_switch_type(&p->in_data.data, MARSHALL);
495                 prs_set_offset(&p->in_data.data, 0);
496                 return ret;
497         }
498
499         return True;
500 }
501
502 /****************************************************************************
503  Processes a finished PDU stored in current_in_pdu. The RPC_HEADER has
504  already been parsed and stored in p->hdr.
505 ****************************************************************************/
506
507 static void process_complete_pdu(pipes_struct *p)
508 {
509         prs_struct rpc_in;
510         size_t data_len = p->in_data.pdu_received_len - RPC_HEADER_LEN;
511         char *data_p = (char *)&p->in_data.current_in_pdu[RPC_HEADER_LEN];
512         bool reply = False;
513
514         if(p->fault_state) {
515                 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
516                           get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
517                 set_incoming_fault(p);
518                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
519                 return;
520         }
521
522         prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
523
524         /*
525          * Ensure we're using the corrent endianness for both the 
526          * RPC header flags and the raw data we will be reading from.
527          */
528
529         prs_set_endian_data( &rpc_in, p->endian);
530         prs_set_endian_data( &p->in_data.data, p->endian);
531
532         prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);
533
534         DEBUG(10,("process_complete_pdu: processing packet type %u\n",
535                         (unsigned int)p->hdr.pkt_type ));
536
537         switch (p->hdr.pkt_type) {
538                 case DCERPC_PKT_REQUEST:
539                         reply = process_request_pdu(p, &rpc_in);
540                         break;
541
542                 case DCERPC_PKT_PING: /* CL request - ignore... */
543                         DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
544                                 (unsigned int)p->hdr.pkt_type,
545                                  get_pipe_name_from_syntax(talloc_tos(),
546                                                            &p->syntax)));
547                         break;
548
549                 case DCERPC_PKT_RESPONSE: /* No responses here. */
550                         DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_RESPONSE received from client on pipe %s.\n",
551                                  get_pipe_name_from_syntax(talloc_tos(),
552                                                            &p->syntax)));
553                         break;
554
555                 case DCERPC_PKT_FAULT:
556                 case DCERPC_PKT_WORKING: /* CL request - reply to a ping when a call in process. */
557                 case DCERPC_PKT_NOCALL: /* CL - server reply to a ping call. */
558                 case DCERPC_PKT_REJECT:
559                 case DCERPC_PKT_ACK:
560                 case DCERPC_PKT_CL_CANCEL:
561                 case DCERPC_PKT_FACK:
562                 case DCERPC_PKT_CANCEL_ACK:
563                         DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
564                                 (unsigned int)p->hdr.pkt_type,
565                                  get_pipe_name_from_syntax(talloc_tos(),
566                                                            &p->syntax)));
567                         break;
568
569                 case DCERPC_PKT_BIND:
570                         /*
571                          * We assume that a pipe bind is only in one pdu.
572                          */
573                         if(pipe_init_outgoing_data(p)) {
574                                 reply = api_pipe_bind_req(p, &rpc_in);
575                         }
576                         break;
577
578                 case DCERPC_PKT_BIND_ACK:
579                 case DCERPC_PKT_BIND_NAK:
580                         DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK packet type %u received on pipe %s.\n",
581                                 (unsigned int)p->hdr.pkt_type,
582                                  get_pipe_name_from_syntax(talloc_tos(),
583                                                            &p->syntax)));
584                         break;
585
586
587                 case DCERPC_PKT_ALTER:
588                         /*
589                          * We assume that a pipe bind is only in one pdu.
590                          */
591                         if(pipe_init_outgoing_data(p)) {
592                                 reply = api_pipe_alter_context(p, &rpc_in);
593                         }
594                         break;
595
596                 case DCERPC_PKT_ALTER_RESP:
597                         DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_ALTER_RESP on pipe %s: Should only be server -> client.\n",
598                                  get_pipe_name_from_syntax(talloc_tos(),
599                                                            &p->syntax)));
600                         break;
601
602                 case DCERPC_PKT_AUTH3:
603                         /*
604                          * The third packet in an NTLMSSP auth exchange.
605                          */
606                         if(pipe_init_outgoing_data(p)) {
607                                 reply = api_pipe_bind_auth3(p, &rpc_in);
608                         }
609                         break;
610
611                 case DCERPC_PKT_SHUTDOWN:
612                         DEBUG(0,("process_complete_pdu: Error. DCERPC_PKT_SHUTDOWN on pipe %s: Should only be server -> client.\n",
613                                  get_pipe_name_from_syntax(talloc_tos(),
614                                                            &p->syntax)));
615                         break;
616
617                 case DCERPC_PKT_CO_CANCEL:
618                         /* For now just free all client data and continue processing. */
619                         DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL. Abandoning rpc call.\n"));
620                         /* As we never do asynchronous RPC serving, we can never cancel a
621                            call (as far as I know). If we ever did we'd have to send a cancel_ack
622                            reply. For now, just free all client data and continue processing. */
623                         reply = True;
624                         break;
625 #if 0
626                         /* Enable this if we're doing async rpc. */
627                         /* We must check the call-id matches the outstanding callid. */
628                         if(pipe_init_outgoing_data(p)) {
629                                 /* Send a cancel_ack PDU reply. */
630                                 /* We should probably check the auth-verifier here. */
631                                 reply = setup_cancel_ack_reply(p, &rpc_in);
632                         }
633                         break;
634 #endif
635
636                 case DCERPC_PKT_ORPHANED:
637                         /* We should probably check the auth-verifier here.
638                            For now just free all client data and continue processing. */
639                         DEBUG(3,("process_complete_pdu: DCERPC_PKT_ORPHANED. Abandoning rpc call.\n"));
640                         reply = True;
641                         break;
642
643                 default:
644                         DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
645                         break;
646         }
647
648         /* Reset to little endian. Probably don't need this but it won't hurt. */
649         prs_set_endian_data( &p->in_data.data, RPC_LITTLE_ENDIAN);
650
651         if (!reply) {
652                 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
653                          "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
654                                                                 &p->syntax)));
655                 set_incoming_fault(p);
656                 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
657                 prs_mem_free(&rpc_in);
658         } else {
659                 /*
660                  * Reset the lengths. We're ready for a new pdu.
661                  */
662                 TALLOC_FREE(p->in_data.current_in_pdu);
663                 p->in_data.pdu_needed_len = 0;
664                 p->in_data.pdu_received_len = 0;
665         }
666
667         prs_mem_free(&rpc_in);
668 }
669
670 /****************************************************************************
671  Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
672 ****************************************************************************/
673
674 static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
675 {
676         size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
677
678         DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
679                 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
680                 (unsigned int)n ));
681
682         if(data_to_copy == 0) {
683                 /*
684                  * This is an error - data is being received and there is no
685                  * space in the PDU. Free the received data and go into the fault state.
686                  */
687                 DEBUG(0,("process_incoming_data: No space in incoming pdu buffer. Current size = %u \
688 incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)n ));
689                 set_incoming_fault(p);
690                 return -1;
691         }
692
693         /*
694          * If we have no data already, wait until we get at least a RPC_HEADER_LEN
695          * number of bytes before we can do anything.
696          */
697
698         if((p->in_data.pdu_needed_len == 0) && (p->in_data.pdu_received_len < RPC_HEADER_LEN)) {
699                 /*
700                  * Always return here. If we have more data then the RPC_HEADER
701                  * will be processed the next time around the loop.
702                  */
703                 return fill_rpc_header(p, data, data_to_copy);
704         }
705
706         /*
707          * At this point we know we have at least an RPC_HEADER_LEN amount of data
708          * stored in current_in_pdu.
709          */
710
711         /*
712          * If pdu_needed_len is zero this is a new pdu. 
713          * Unmarshall the header so we know how much more
714          * data we need, then loop again.
715          */
716
717         if(p->in_data.pdu_needed_len == 0) {
718                 ssize_t rret = unmarshall_rpc_header(p);
719                 if (rret == -1 || p->in_data.pdu_needed_len > 0) {
720                         return rret;
721                 }
722                 /* If rret == 0 and pdu_needed_len == 0 here we have a PDU that consists
723                    of an RPC_HEADER only. This is a DCERPC_PKT_SHUTDOWN, DCERPC_PKT_CO_CANCEL or DCERPC_PKT_ORPHANED
724                    pdu type. Deal with this in process_complete_pdu(). */
725         }
726
727         /*
728          * Ok - at this point we have a valid RPC_HEADER in p->hdr.
729          * Keep reading until we have a full pdu.
730          */
731
732         data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
733
734         /*
735          * Copy as much of the data as we need into the current_in_pdu buffer.
736          * pdu_needed_len becomes zero when we have a complete pdu.
737          */
738
739         memcpy( (char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, data_to_copy);
740         p->in_data.pdu_received_len += data_to_copy;
741         p->in_data.pdu_needed_len -= data_to_copy;
742
743         /*
744          * Do we have a complete PDU ?
745          * (return the number of bytes handled in the call)
746          */
747
748         if(p->in_data.pdu_needed_len == 0) {
749                 process_complete_pdu(p);
750                 return data_to_copy;
751         }
752
753         DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
754                 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
755
756         return (ssize_t)data_to_copy;
757 }
758
759 /****************************************************************************
760  Accepts incoming data on an internal rpc pipe.
761 ****************************************************************************/
762
763 static ssize_t write_to_internal_pipe(struct pipes_struct *p, char *data, size_t n)
764 {
765         size_t data_left = n;
766
767         while(data_left) {
768                 ssize_t data_used;
769
770                 DEBUG(10,("write_to_pipe: data_left = %u\n", (unsigned int)data_left ));
771
772                 data_used = process_incoming_data(p, data, data_left);
773
774                 DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
775
776                 if(data_used < 0) {
777                         return -1;
778                 }
779
780                 data_left -= data_used;
781                 data += data_used;
782         }       
783
784         return n;
785 }
786
787 /****************************************************************************
788  Replies to a request to read data from a pipe.
789
790  Headers are interspersed with the data at PDU intervals. By the time
791  this function is called, the start of the data could possibly have been
792  read by an SMBtrans (file_offset != 0).
793
794  Calling create_rpc_reply() here is a hack. The data should already
795  have been prepared into arrays of headers + data stream sections.
796 ****************************************************************************/
797
798 static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data, size_t n,
799                                        bool *is_data_outstanding)
800 {
801         uint32 pdu_remaining = 0;
802         ssize_t data_returned = 0;
803
804         if (!p) {
805                 DEBUG(0,("read_from_pipe: pipe not open\n"));
806                 return -1;              
807         }
808
809         DEBUG(6,(" name: %s len: %u\n",
810                  get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
811                  (unsigned int)n));
812
813         /*
814          * We cannot return more than one PDU length per
815          * read request.
816          */
817
818         /*
819          * This condition should result in the connection being closed.  
820          * Netapp filers seem to set it to 0xffff which results in domain
821          * authentications failing.  Just ignore it so things work.
822          */
823
824         if(n > RPC_MAX_PDU_FRAG_LEN) {
825                 DEBUG(5,("read_from_pipe: too large read (%u) requested on "
826                          "pipe %s. We can only service %d sized reads.\n",
827                          (unsigned int)n,
828                          get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
829                          RPC_MAX_PDU_FRAG_LEN ));
830                 n = RPC_MAX_PDU_FRAG_LEN;
831         }
832
833         /*
834          * Determine if there is still data to send in the
835          * pipe PDU buffer. Always send this first. Never
836          * send more than is left in the current PDU. The
837          * client should send a new read request for a new
838          * PDU.
839          */
840
841         pdu_remaining = prs_offset(&p->out_data.frag)
842                 - p->out_data.current_pdu_sent;
843
844         if (pdu_remaining > 0) {
845                 data_returned = (ssize_t)MIN(n, pdu_remaining);
846
847                 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
848                           "current_pdu_sent = %u returning %d bytes.\n",
849                           get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
850                           (unsigned int)prs_offset(&p->out_data.frag),
851                           (unsigned int)p->out_data.current_pdu_sent,
852                           (int)data_returned));
853
854                 memcpy(data,
855                        prs_data_p(&p->out_data.frag)
856                        + p->out_data.current_pdu_sent,
857                        data_returned);
858
859                 p->out_data.current_pdu_sent += (uint32)data_returned;
860                 goto out;
861         }
862
863         /*
864          * At this point p->current_pdu_len == p->current_pdu_sent (which
865          * may of course be zero if this is the first return fragment.
866          */
867
868         DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
869                   "= %u, prs_offset(&p->out_data.rdata) = %u.\n",
870                   get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
871                   (int)p->fault_state,
872                   (unsigned int)p->out_data.data_sent_length,
873                   (unsigned int)prs_offset(&p->out_data.rdata) ));
874
875         if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
876                 /*
877                  * We have sent all possible data, return 0.
878                  */
879                 data_returned = 0;
880                 goto out;
881         }
882
883         /*
884          * We need to create a new PDU from the data left in p->rdata.
885          * Create the header/data/footers. This also sets up the fields
886          * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
887          * and stores the outgoing PDU in p->current_pdu.
888          */
889
890         if(!create_next_pdu(p)) {
891                 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
892                          get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
893                 return -1;
894         }
895
896         data_returned = MIN(n, prs_offset(&p->out_data.frag));
897
898         memcpy( data, prs_data_p(&p->out_data.frag), (size_t)data_returned);
899         p->out_data.current_pdu_sent += (uint32)data_returned;
900
901   out:
902         (*is_data_outstanding) = prs_offset(&p->out_data.frag) > n;
903
904         if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
905                 /* We've returned everything in the out_data.frag
906                  * so we're done with this pdu. Free it and reset
907                  * current_pdu_sent. */
908                 p->out_data.current_pdu_sent = 0;
909                 prs_mem_free(&p->out_data.frag);
910         }
911         return data_returned;
912 }
913
914 /****************************************************************************
915  Close an rpc pipe.
916 ****************************************************************************/
917
918 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
919 {
920         if (!p) {
921                 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
922                 return False;
923         }
924
925         prs_mem_free(&p->out_data.frag);
926         prs_mem_free(&p->out_data.rdata);
927         prs_mem_free(&p->in_data.data);
928
929         if (p->auth.auth_data_free_func) {
930                 (*p->auth.auth_data_free_func)(&p->auth);
931         }
932
933         free_pipe_rpc_context( p->contexts );
934
935         /* Free the handles database. */
936         close_policy_by_pipe(p);
937
938         DLIST_REMOVE(InternalPipes, p);
939
940         ZERO_STRUCTP(p);
941
942         return 0;
943 }
944
945 bool fsp_is_np(struct files_struct *fsp)
946 {
947         enum FAKE_FILE_TYPE type;
948
949         if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
950                 return false;
951         }
952
953         type = fsp->fake_file_handle->type;
954
955         return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
956                 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
957 }
958
959 struct np_proxy_state {
960         uint16_t file_type;
961         uint16_t device_state;
962         uint64_t allocation_size;
963         struct tstream_context *npipe;
964         struct tevent_queue *read_queue;
965         struct tevent_queue *write_queue;
966 };
967
968 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
969                                 const char *pipe_name,
970                                 const struct tsocket_address *local_address,
971                                 const struct tsocket_address *remote_address,
972                                 struct auth_serversupplied_info *server_info)
973 {
974         struct np_proxy_state *result;
975         char *socket_np_dir;
976         const char *socket_dir;
977         struct tevent_context *ev;
978         struct tevent_req *subreq;
979         struct netr_SamInfo3 *info3;
980         NTSTATUS status;
981         bool ok;
982         int ret;
983         int sys_errno;
984
985         result = talloc(mem_ctx, struct np_proxy_state);
986         if (result == NULL) {
987                 DEBUG(0, ("talloc failed\n"));
988                 return NULL;
989         }
990
991         result->read_queue = tevent_queue_create(result, "np_read");
992         if (result->read_queue == NULL) {
993                 DEBUG(0, ("tevent_queue_create failed\n"));
994                 goto fail;
995         }
996
997         result->write_queue = tevent_queue_create(result, "np_write");
998         if (result->write_queue == NULL) {
999                 DEBUG(0, ("tevent_queue_create failed\n"));
1000                 goto fail;
1001         }
1002
1003         ev = s3_tevent_context_init(talloc_tos());
1004         if (ev == NULL) {
1005                 DEBUG(0, ("s3_tevent_context_init failed\n"));
1006                 goto fail;
1007         }
1008
1009         socket_dir = lp_parm_const_string(
1010                 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
1011                 get_dyn_NCALRPCDIR());
1012         if (socket_dir == NULL) {
1013                 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
1014                 goto fail;
1015         }
1016         socket_np_dir = talloc_asprintf(talloc_tos(), "%s/np", socket_dir);
1017         if (socket_np_dir == NULL) {
1018                 DEBUG(0, ("talloc_asprintf failed\n"));
1019                 goto fail;
1020         }
1021
1022         info3 = talloc_zero(talloc_tos(), struct netr_SamInfo3);
1023         if (info3 == NULL) {
1024                 DEBUG(0, ("talloc failed\n"));
1025                 goto fail;
1026         }
1027
1028         status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
1029         if (!NT_STATUS_IS_OK(status)) {
1030                 TALLOC_FREE(info3);
1031                 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
1032                           nt_errstr(status)));
1033                 goto fail;
1034         }
1035
1036         become_root();
1037         subreq = tstream_npa_connect_send(talloc_tos(), ev,
1038                                           socket_np_dir,
1039                                           pipe_name,
1040                                           remote_address, /* client_addr */
1041                                           NULL, /* client_name */
1042                                           local_address, /* server_addr */
1043                                           NULL, /* server_name */
1044                                           info3,
1045                                           server_info->user_session_key,
1046                                           data_blob_null /* delegated_creds */);
1047         if (subreq == NULL) {
1048                 unbecome_root();
1049                 DEBUG(0, ("tstream_npa_connect_send failed\n"));
1050                 goto fail;
1051         }
1052         ok = tevent_req_poll(subreq, ev);
1053         unbecome_root();
1054         if (!ok) {
1055                 DEBUG(0, ("tevent_req_poll failed for tstream_npa_connect: %s\n",
1056                           strerror(errno)));
1057                 goto fail;
1058
1059         }
1060         ret = tstream_npa_connect_recv(subreq, &sys_errno,
1061                                        result,
1062                                        &result->npipe,
1063                                        &result->file_type,
1064                                        &result->device_state,
1065                                        &result->allocation_size);
1066         TALLOC_FREE(subreq);
1067         if (ret != 0) {
1068                 DEBUG(0, ("tstream_npa_connect_recv failed: %s\n",
1069                           strerror(sys_errno)));
1070                 goto fail;
1071         }
1072
1073         return result;
1074
1075  fail:
1076         TALLOC_FREE(result);
1077         return NULL;
1078 }
1079
1080 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
1081                  const struct tsocket_address *local_address,
1082                  const struct tsocket_address *remote_address,
1083                  struct auth_serversupplied_info *server_info,
1084                  struct fake_file_handle **phandle)
1085 {
1086         const char **proxy_list;
1087         struct fake_file_handle *handle;
1088
1089         proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
1090
1091         handle = talloc(mem_ctx, struct fake_file_handle);
1092         if (handle == NULL) {
1093                 return NT_STATUS_NO_MEMORY;
1094         }
1095
1096         if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
1097                 struct np_proxy_state *p;
1098
1099                 p = make_external_rpc_pipe_p(handle, name,
1100                                              local_address,
1101                                              remote_address,
1102                                              server_info);
1103
1104                 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
1105                 handle->private_data = p;
1106         } else {
1107                 struct pipes_struct *p;
1108                 struct ndr_syntax_id syntax;
1109                 const char *client_address;
1110
1111                 if (!is_known_pipename(name, &syntax)) {
1112                         TALLOC_FREE(handle);
1113                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1114                 }
1115
1116                 if (tsocket_address_is_inet(remote_address, "ip")) {
1117                         client_address = tsocket_address_inet_addr_string(
1118                                                 remote_address,
1119                                                 talloc_tos());
1120                         if (client_address == NULL) {
1121                                 TALLOC_FREE(handle);
1122                                 return NT_STATUS_NO_MEMORY;
1123                         }
1124                 } else {
1125                         client_address = "";
1126                 }
1127
1128                 p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
1129                                              server_info);
1130
1131                 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
1132                 handle->private_data = p;
1133         }
1134
1135         if (handle->private_data == NULL) {
1136                 TALLOC_FREE(handle);
1137                 return NT_STATUS_PIPE_NOT_AVAILABLE;
1138         }
1139
1140         *phandle = handle;
1141
1142         return NT_STATUS_OK;
1143 }
1144
1145 bool np_read_in_progress(struct fake_file_handle *handle)
1146 {
1147         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1148                 return false;
1149         }
1150
1151         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1152                 struct np_proxy_state *p = talloc_get_type_abort(
1153                         handle->private_data, struct np_proxy_state);
1154                 size_t read_count;
1155
1156                 read_count = tevent_queue_length(p->read_queue);
1157                 if (read_count > 0) {
1158                         return true;
1159                 }
1160
1161                 return false;
1162         }
1163
1164         return false;
1165 }
1166
1167 struct np_write_state {
1168         struct event_context *ev;
1169         struct np_proxy_state *p;
1170         struct iovec iov;
1171         ssize_t nwritten;
1172 };
1173
1174 static void np_write_done(struct tevent_req *subreq);
1175
1176 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1177                                  struct fake_file_handle *handle,
1178                                  const uint8_t *data, size_t len)
1179 {
1180         struct tevent_req *req;
1181         struct np_write_state *state;
1182         NTSTATUS status;
1183
1184         DEBUG(6, ("np_write_send: len: %d\n", (int)len));
1185         dump_data(50, data, len);
1186
1187         req = tevent_req_create(mem_ctx, &state, struct np_write_state);
1188         if (req == NULL) {
1189                 return NULL;
1190         }
1191
1192         if (len == 0) {
1193                 state->nwritten = 0;
1194                 status = NT_STATUS_OK;
1195                 goto post_status;
1196         }
1197
1198         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1199                 struct pipes_struct *p = talloc_get_type_abort(
1200                         handle->private_data, struct pipes_struct);
1201
1202                 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
1203
1204                 status = (state->nwritten >= 0)
1205                         ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1206                 goto post_status;
1207         }
1208
1209         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1210                 struct np_proxy_state *p = talloc_get_type_abort(
1211                         handle->private_data, struct np_proxy_state);
1212                 struct tevent_req *subreq;
1213
1214                 state->ev = ev;
1215                 state->p = p;
1216                 state->iov.iov_base = CONST_DISCARD(void *, data);
1217                 state->iov.iov_len = len;
1218
1219                 subreq = tstream_writev_queue_send(state, ev,
1220                                                    p->npipe,
1221                                                    p->write_queue,
1222                                                    &state->iov, 1);
1223                 if (subreq == NULL) {
1224                         goto fail;
1225                 }
1226                 tevent_req_set_callback(subreq, np_write_done, req);
1227                 return req;
1228         }
1229
1230         status = NT_STATUS_INVALID_HANDLE;
1231  post_status:
1232         if (NT_STATUS_IS_OK(status)) {
1233                 tevent_req_done(req);
1234         } else {
1235                 tevent_req_nterror(req, status);
1236         }
1237         return tevent_req_post(req, ev);
1238  fail:
1239         TALLOC_FREE(req);
1240         return NULL;
1241 }
1242
1243 static void np_write_done(struct tevent_req *subreq)
1244 {
1245         struct tevent_req *req = tevent_req_callback_data(
1246                 subreq, struct tevent_req);
1247         struct np_write_state *state = tevent_req_data(
1248                 req, struct np_write_state);
1249         ssize_t received;
1250         int err;
1251
1252         received = tstream_writev_queue_recv(subreq, &err);
1253         if (received < 0) {
1254                 tevent_req_nterror(req, map_nt_error_from_unix(err));
1255                 return;
1256         }
1257         state->nwritten = received;
1258         tevent_req_done(req);
1259 }
1260
1261 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
1262 {
1263         struct np_write_state *state = tevent_req_data(
1264                 req, struct np_write_state);
1265         NTSTATUS status;
1266
1267         if (tevent_req_is_nterror(req, &status)) {
1268                 return status;
1269         }
1270         *pnwritten = state->nwritten;
1271         return NT_STATUS_OK;
1272 }
1273
1274 struct np_ipc_readv_next_vector_state {
1275         uint8_t *buf;
1276         size_t len;
1277         off_t ofs;
1278         size_t remaining;
1279 };
1280
1281 static void np_ipc_readv_next_vector_init(struct np_ipc_readv_next_vector_state *s,
1282                                           uint8_t *buf, size_t len)
1283 {
1284         ZERO_STRUCTP(s);
1285
1286         s->buf = buf;
1287         s->len = MIN(len, UINT16_MAX);
1288 }
1289
1290 static int np_ipc_readv_next_vector(struct tstream_context *stream,
1291                                     void *private_data,
1292                                     TALLOC_CTX *mem_ctx,
1293                                     struct iovec **_vector,
1294                                     size_t *count)
1295 {
1296         struct np_ipc_readv_next_vector_state *state =
1297                 (struct np_ipc_readv_next_vector_state *)private_data;
1298         struct iovec *vector;
1299         ssize_t pending;
1300         size_t wanted;
1301
1302         if (state->ofs == state->len) {
1303                 *_vector = NULL;
1304                 *count = 0;
1305                 return 0;
1306         }
1307
1308         pending = tstream_pending_bytes(stream);
1309         if (pending == -1) {
1310                 return -1;
1311         }
1312
1313         if (pending == 0 && state->ofs != 0) {
1314                 /* return a short read */
1315                 *_vector = NULL;
1316                 *count = 0;
1317                 return 0;
1318         }
1319
1320         if (pending == 0) {
1321                 /* we want at least one byte and recheck again */
1322                 wanted = 1;
1323         } else {
1324                 size_t missing = state->len - state->ofs;
1325                 if (pending > missing) {
1326                         /* there's more available */
1327                         state->remaining = pending - missing;
1328                         wanted = missing;
1329                 } else {
1330                         /* read what we can get and recheck in the next cycle */
1331                         wanted = pending;
1332                 }
1333         }
1334
1335         vector = talloc_array(mem_ctx, struct iovec, 1);
1336         if (!vector) {
1337                 return -1;
1338         }
1339
1340         vector[0].iov_base = state->buf + state->ofs;
1341         vector[0].iov_len = wanted;
1342
1343         state->ofs += wanted;
1344
1345         *_vector = vector;
1346         *count = 1;
1347         return 0;
1348 }
1349
1350 struct np_read_state {
1351         struct np_proxy_state *p;
1352         struct np_ipc_readv_next_vector_state next_vector;
1353
1354         size_t nread;
1355         bool is_data_outstanding;
1356 };
1357
1358 static void np_read_done(struct tevent_req *subreq);
1359
1360 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1361                                 struct fake_file_handle *handle,
1362                                 uint8_t *data, size_t len)
1363 {
1364         struct tevent_req *req;
1365         struct np_read_state *state;
1366         NTSTATUS status;
1367
1368         req = tevent_req_create(mem_ctx, &state, struct np_read_state);
1369         if (req == NULL) {
1370                 return NULL;
1371         }
1372
1373         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1374                 struct pipes_struct *p = talloc_get_type_abort(
1375                         handle->private_data, struct pipes_struct);
1376
1377                 state->nread = read_from_internal_pipe(
1378                         p, (char *)data, len, &state->is_data_outstanding);
1379
1380                 status = (state->nread >= 0)
1381                         ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1382                 goto post_status;
1383         }
1384
1385         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1386                 struct np_proxy_state *p = talloc_get_type_abort(
1387                         handle->private_data, struct np_proxy_state);
1388                 struct tevent_req *subreq;
1389
1390                 np_ipc_readv_next_vector_init(&state->next_vector,
1391                                               data, len);
1392
1393                 subreq = tstream_readv_pdu_queue_send(state,
1394                                                       ev,
1395                                                       p->npipe,
1396                                                       p->read_queue,
1397                                                       np_ipc_readv_next_vector,
1398                                                       &state->next_vector);
1399                 if (subreq == NULL) {
1400
1401                 }
1402                 tevent_req_set_callback(subreq, np_read_done, req);
1403                 return req;
1404         }
1405
1406         status = NT_STATUS_INVALID_HANDLE;
1407  post_status:
1408         if (NT_STATUS_IS_OK(status)) {
1409                 tevent_req_done(req);
1410         } else {
1411                 tevent_req_nterror(req, status);
1412         }
1413         return tevent_req_post(req, ev);
1414 }
1415
1416 static void np_read_done(struct tevent_req *subreq)
1417 {
1418         struct tevent_req *req = tevent_req_callback_data(
1419                 subreq, struct tevent_req);
1420         struct np_read_state *state = tevent_req_data(
1421                 req, struct np_read_state);
1422         ssize_t ret;
1423         int err;
1424
1425         ret = tstream_readv_pdu_queue_recv(subreq, &err);
1426         TALLOC_FREE(subreq);
1427         if (ret == -1) {
1428                 tevent_req_nterror(req, map_nt_error_from_unix(err));
1429                 return;
1430         }
1431
1432         state->nread = ret;
1433         state->is_data_outstanding = (state->next_vector.remaining > 0);
1434
1435         tevent_req_done(req);
1436         return;
1437 }
1438
1439 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
1440                       bool *is_data_outstanding)
1441 {
1442         struct np_read_state *state = tevent_req_data(
1443                 req, struct np_read_state);
1444         NTSTATUS status;
1445
1446         if (tevent_req_is_nterror(req, &status)) {
1447                 return status;
1448         }
1449         *nread = state->nread;
1450         *is_data_outstanding = state->is_data_outstanding;
1451         return NT_STATUS_OK;
1452 }
1453
1454 /**
1455  * @brief Create a new RPC client context which uses a local dispatch function.
1456  *
1457  * @param[in]  mem_ctx  The memory context to use.
1458  *
1459  * @param[in]  abstract_syntax Normally the syntax_id of the autogenerated
1460  *                             ndr_table_<name>.
1461  *
1462  * @param[in]  dispatch The corresponding autogenerated dispatch function
1463  *                      rpc_<name>_dispatch.
1464  *
1465  * @param[in]  serversupplied_info The server supplied authentication function.
1466  *
1467  * @param[out] presult  A pointer to store the connected rpc client pipe.
1468  *
1469  * @return              NT_STATUS_OK on success, a corresponding NT status if an
1470  *                      error occured.
1471  *
1472  * @code
1473  *   struct rpc_pipe_client *winreg_pipe;
1474  *   NTSTATUS status;
1475  *
1476  *   status = rpc_pipe_open_internal(tmp_ctx,
1477  *                                   &ndr_table_winreg.syntax_id,
1478  *                                   rpc_winreg_dispatch,
1479  *                                   p->server_info,
1480  *                                   &winreg_pipe);
1481  * @endcode
1482  */
1483 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
1484                                 const struct ndr_syntax_id *abstract_syntax,
1485                                 NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
1486                                                       TALLOC_CTX *mem_ctx,
1487                                                       const struct ndr_interface_table *table,
1488                                                       uint32_t opnum, void *r),
1489                                 struct auth_serversupplied_info *serversupplied_info,
1490                                 struct rpc_pipe_client **presult)
1491 {
1492         struct rpc_pipe_client *result;
1493
1494         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
1495         if (result == NULL) {
1496                 return NT_STATUS_NO_MEMORY;
1497         }
1498
1499         result->abstract_syntax = *abstract_syntax;
1500         result->transfer_syntax = ndr_transfer_syntax;
1501         result->dispatch = dispatch;
1502
1503         result->pipes_struct = make_internal_rpc_pipe_p(
1504                 result, abstract_syntax, "", serversupplied_info);
1505         if (result->pipes_struct == NULL) {
1506                 TALLOC_FREE(result);
1507                 return NT_STATUS_NO_MEMORY;
1508         }
1509
1510         result->max_xmit_frag = -1;
1511         result->max_recv_frag = -1;
1512
1513         *presult = result;
1514         return NT_STATUS_OK;
1515 }
1516
1517 /**
1518  * @brief Create a new RPC client context which uses a local dispatch function.
1519  *
1520  * @param[in]  conn  The connection struct that will hold the pipe
1521  *
1522  * @param[out] spoolss_pipe  A pointer to the connected rpc client pipe.
1523  *
1524  * @return              NT_STATUS_OK on success, a corresponding NT status if an
1525  *                      error occured.
1526  */
1527 NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn,
1528                                   struct rpc_pipe_client **spoolss_pipe)
1529 {
1530         NTSTATUS status;
1531
1532         /* TODO: check and handle disconnections */
1533
1534         if (!conn->spoolss_pipe) {
1535                 status = rpc_pipe_open_internal(conn,
1536                                                 &ndr_table_spoolss.syntax_id,
1537                                                 rpc_spoolss_dispatch,
1538                                                 conn->server_info,
1539                                                 &conn->spoolss_pipe);
1540                 if (!NT_STATUS_IS_OK(status)) {
1541                         return status;
1542                 }
1543         }
1544
1545         *spoolss_pipe = conn->spoolss_pipe;
1546         return NT_STATUS_OK;
1547 }