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