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