Merge branch 'master' of git://git.samba.org/samba
[idra/samba.git] / source3 / rpc_server / srv_pipe_hnd.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1998,
5  *  Largely re-written : 2005
6  *  Copyright (C) Jeremy Allison                1998 - 2005
7  *  
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 3 of the License, or
11  *  (at your option) any later version.
12  *  
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *  
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/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         if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
907                 /* We've returned everything in the out_data.frag
908                  * so we're done with this pdu. Free it and reset
909                  * current_pdu_sent. */
910                 p->out_data.current_pdu_sent = 0;
911                 prs_mem_free(&p->out_data.frag);
912         }
913         return data_returned;
914 }
915
916 /****************************************************************************
917  Close an rpc pipe.
918 ****************************************************************************/
919
920 static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
921 {
922         if (!p) {
923                 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
924                 return False;
925         }
926
927         prs_mem_free(&p->out_data.frag);
928         prs_mem_free(&p->out_data.rdata);
929         prs_mem_free(&p->in_data.data);
930
931         if (p->auth.auth_data_free_func) {
932                 (*p->auth.auth_data_free_func)(&p->auth);
933         }
934
935         TALLOC_FREE(p->mem_ctx);
936
937         free_pipe_rpc_context( p->contexts );
938
939         /* Free the handles database. */
940         close_policy_by_pipe(p);
941
942         DLIST_REMOVE(InternalPipes, p);
943
944         ZERO_STRUCTP(p);
945
946         TALLOC_FREE(p);
947         
948         return True;
949 }
950
951 bool fsp_is_np(struct files_struct *fsp)
952 {
953         enum FAKE_FILE_TYPE type;
954
955         if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
956                 return false;
957         }
958
959         type = fsp->fake_file_handle->type;
960
961         return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
962                 || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
963 }
964
965 struct np_proxy_state {
966         struct tevent_queue *read_queue;
967         struct tevent_queue *write_queue;
968         int fd;
969
970         uint8_t *msg;
971         size_t sent;
972 };
973
974 static int np_proxy_state_destructor(struct np_proxy_state *state)
975 {
976         if (state->fd != -1) {
977                 close(state->fd);
978         }
979         return 0;
980 }
981
982 static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
983                                                        const char *pipe_name,
984                                                        struct auth_serversupplied_info *server_info)
985 {
986         struct np_proxy_state *result;
987         struct sockaddr_un addr;
988         char *socket_path;
989         const char *socket_dir;
990
991         DATA_BLOB req_blob;
992         struct netr_SamInfo3 *info3;
993         struct named_pipe_auth_req req;
994         DATA_BLOB rep_blob;
995         uint8 rep_buf[20];
996         struct named_pipe_auth_rep rep;
997         enum ndr_err_code ndr_err;
998         NTSTATUS status;
999         ssize_t written;
1000
1001         result = talloc(mem_ctx, struct np_proxy_state);
1002         if (result == NULL) {
1003                 DEBUG(0, ("talloc failed\n"));
1004                 return NULL;
1005         }
1006
1007         result->fd = socket(AF_UNIX, SOCK_STREAM, 0);
1008         if (result->fd == -1) {
1009                 DEBUG(10, ("socket(2) failed: %s\n", strerror(errno)));
1010                 goto fail;
1011         }
1012         talloc_set_destructor(result, np_proxy_state_destructor);
1013
1014         ZERO_STRUCT(addr);
1015         addr.sun_family = AF_UNIX;
1016
1017         socket_dir = lp_parm_const_string(
1018                 GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
1019                 get_dyn_NCALRPCDIR());
1020         if (socket_dir == NULL) {
1021                 DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
1022                 goto fail;
1023         }
1024
1025         socket_path = talloc_asprintf(talloc_tos(), "%s/np/%s",
1026                                       socket_dir, pipe_name);
1027         if (socket_path == NULL) {
1028                 DEBUG(0, ("talloc_asprintf failed\n"));
1029                 goto fail;
1030         }
1031         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
1032         TALLOC_FREE(socket_path);
1033
1034         become_root();
1035         if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
1036                 unbecome_root();
1037                 DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
1038                           strerror(errno)));
1039                 goto fail;
1040         }
1041         unbecome_root();
1042
1043         info3 = talloc(talloc_tos(), struct netr_SamInfo3);
1044         if (info3 == NULL) {
1045                 DEBUG(0, ("talloc failed\n"));
1046                 goto fail;
1047         }
1048
1049         status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
1050         if (!NT_STATUS_IS_OK(status)) {
1051                 TALLOC_FREE(info3);
1052                 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
1053                           nt_errstr(status)));
1054                 goto fail;
1055         }
1056
1057         req.level = 1;
1058         req.info.info1 = *info3;
1059
1060         ndr_err = ndr_push_struct_blob(
1061                 &req_blob, talloc_tos(), NULL, &req,
1062                 (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
1063
1064         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1065                 DEBUG(10, ("ndr_push_named_pipe_auth_req failed: %s\n",
1066                            ndr_errstr(ndr_err)));
1067                 goto fail;
1068         }
1069
1070         DEBUG(10, ("named_pipe_auth_req(client)[%u]\n", (uint32_t)req_blob.length));
1071         dump_data(10, req_blob.data, req_blob.length);
1072
1073         written = write_data(result->fd, (char *)req_blob.data,
1074                              req_blob.length);
1075         if (written == -1) {
1076                 DEBUG(3, ("Could not write auth req data to RPC server\n"));
1077                 goto fail;
1078         }
1079
1080         status = read_data(result->fd, (char *)rep_buf, sizeof(rep_buf));
1081         if (!NT_STATUS_IS_OK(status)) {
1082                 DEBUG(3, ("Could not read auth result\n"));
1083                 goto fail;
1084         }
1085
1086         rep_blob = data_blob_const(rep_buf, sizeof(rep_buf));
1087
1088         DEBUG(10,("name_pipe_auth_rep(client)[%u]\n", (uint32_t)rep_blob.length));
1089         dump_data(10, rep_blob.data, rep_blob.length);
1090
1091         ndr_err = ndr_pull_struct_blob(
1092                 &rep_blob, talloc_tos(), NULL, &rep,
1093                 (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep);
1094
1095         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1096                 DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n",
1097                           ndr_errstr(ndr_err)));
1098                 goto fail;
1099         }
1100
1101         if (rep.length != 16) {
1102                 DEBUG(0, ("req invalid length: %u != 16\n",
1103                           rep.length));
1104                 goto fail;
1105         }
1106
1107         if (strcmp(NAMED_PIPE_AUTH_MAGIC, rep.magic) != 0) {
1108                 DEBUG(0, ("req invalid magic: %s != %s\n",
1109                           rep.magic, NAMED_PIPE_AUTH_MAGIC));
1110                 goto fail;
1111         }
1112
1113         if (!NT_STATUS_IS_OK(rep.status)) {
1114                 DEBUG(0, ("req failed: %s\n",
1115                           nt_errstr(rep.status)));
1116                 goto fail;
1117         }
1118
1119         if (rep.level != 1) {
1120                 DEBUG(0, ("req invalid level: %u != 1\n",
1121                           rep.level));
1122                 goto fail;
1123         }
1124
1125         result->msg = NULL;
1126
1127         result->read_queue = tevent_queue_create(result, "np_read");
1128         if (result->read_queue == NULL) {
1129                 goto fail;
1130         }
1131         result->write_queue = tevent_queue_create(result, "np_write");
1132         if (result->write_queue == NULL) {
1133                 goto fail;
1134         }
1135
1136         return result;
1137
1138  fail:
1139         TALLOC_FREE(result);
1140         return NULL;
1141 }
1142
1143 NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
1144                  const char *client_address,
1145                  struct auth_serversupplied_info *server_info,
1146                  struct fake_file_handle **phandle)
1147 {
1148         const char **proxy_list;
1149         struct fake_file_handle *handle;
1150
1151         proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL);
1152
1153         handle = talloc(mem_ctx, struct fake_file_handle);
1154         if (handle == NULL) {
1155                 return NT_STATUS_NO_MEMORY;
1156         }
1157
1158         if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
1159                 struct np_proxy_state *p;
1160
1161                 p = make_external_rpc_pipe_p(handle, name, server_info);
1162
1163                 handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
1164                 handle->private_data = p;
1165         } else {
1166                 struct pipes_struct *p;
1167                 struct ndr_syntax_id syntax;
1168
1169                 if (!is_known_pipename(name, &syntax)) {
1170                         TALLOC_FREE(handle);
1171                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1172                 }
1173
1174                 p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
1175                                              server_info);
1176
1177                 handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
1178                 handle->private_data = p;
1179         }
1180
1181         if (handle->private_data == NULL) {
1182                 TALLOC_FREE(handle);
1183                 return NT_STATUS_PIPE_NOT_AVAILABLE;
1184         }
1185
1186         *phandle = handle;
1187
1188         return NT_STATUS_OK;
1189 }
1190
1191 struct np_write_state {
1192         struct event_context *ev;
1193         struct np_proxy_state *p;
1194         struct iovec iov;
1195         ssize_t nwritten;
1196 };
1197
1198 static void np_write_done(struct tevent_req *subreq);
1199
1200 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1201                                  struct fake_file_handle *handle,
1202                                  const uint8_t *data, size_t len)
1203 {
1204         struct tevent_req *req;
1205         struct np_write_state *state;
1206         NTSTATUS status;
1207
1208         DEBUG(6, ("np_write_send: len: %d\n", (int)len));
1209         dump_data(50, data, len);
1210
1211         req = tevent_req_create(mem_ctx, &state, struct np_write_state);
1212         if (req == NULL) {
1213                 return NULL;
1214         }
1215
1216         if (len == 0) {
1217                 state->nwritten = 0;
1218                 status = NT_STATUS_OK;
1219                 goto post_status;
1220         }
1221
1222         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1223                 struct pipes_struct *p = talloc_get_type_abort(
1224                         handle->private_data, struct pipes_struct);
1225
1226                 state->nwritten = write_to_internal_pipe(p, (char *)data, len);
1227
1228                 status = (state->nwritten >= 0)
1229                         ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1230                 goto post_status;
1231         }
1232
1233         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1234                 struct np_proxy_state *p = talloc_get_type_abort(
1235                         handle->private_data, struct np_proxy_state);
1236                 struct tevent_req *subreq;
1237
1238                 state->ev = ev;
1239                 state->p = p;
1240                 state->iov.iov_base = CONST_DISCARD(void *, data);
1241                 state->iov.iov_len = len;
1242
1243                 subreq = writev_send(state, ev, p->write_queue, p->fd,
1244                                      false, &state->iov, 1);
1245                 if (subreq == NULL) {
1246                         goto fail;
1247                 }
1248                 tevent_req_set_callback(subreq, np_write_done, req);
1249                 return req;
1250         }
1251
1252         status = NT_STATUS_INVALID_HANDLE;
1253  post_status:
1254         if (NT_STATUS_IS_OK(status)) {
1255                 tevent_req_done(req);
1256         } else {
1257                 tevent_req_nterror(req, status);
1258         }
1259         return tevent_req_post(req, ev);
1260  fail:
1261         TALLOC_FREE(req);
1262         return NULL;
1263 }
1264
1265 static void np_write_done(struct tevent_req *subreq)
1266 {
1267         struct tevent_req *req = tevent_req_callback_data(
1268                 subreq, struct tevent_req);
1269         struct np_write_state *state = tevent_req_data(
1270                 req, struct np_write_state);
1271         ssize_t received;
1272         int err;
1273
1274         received = writev_recv(subreq, &err);
1275         if (received < 0) {
1276                 tevent_req_nterror(req, map_nt_error_from_unix(err));
1277                 return;
1278         }
1279         state->nwritten = received;
1280         tevent_req_done(req);
1281 }
1282
1283 NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
1284 {
1285         struct np_write_state *state = tevent_req_data(
1286                 req, struct np_write_state);
1287         NTSTATUS status;
1288
1289         if (tevent_req_is_nterror(req, &status)) {
1290                 return status;
1291         }
1292         *pnwritten = state->nwritten;
1293         return NT_STATUS_OK;
1294 }
1295
1296 static ssize_t rpc_frag_more_fn(uint8_t *buf, size_t buflen, void *priv)
1297 {
1298         prs_struct hdr_prs;
1299         struct rpc_hdr_info hdr;
1300         bool ret;
1301
1302         if (buflen > RPC_HEADER_LEN) {
1303                 return 0;
1304         }
1305         prs_init_empty(&hdr_prs, talloc_tos(), UNMARSHALL);
1306         prs_give_memory(&hdr_prs, (char *)buf, RPC_HEADER_LEN, false);
1307         ret = smb_io_rpc_hdr("", &hdr, &hdr_prs, 0);
1308         prs_mem_free(&hdr_prs);
1309
1310         if (!ret) {
1311                 return -1;
1312         }
1313
1314         return (hdr.frag_len - RPC_HEADER_LEN);
1315 }
1316
1317 struct np_read_state {
1318         struct event_context *ev;
1319         struct np_proxy_state *p;
1320         uint8_t *data;
1321         size_t len;
1322
1323         size_t nread;
1324         bool is_data_outstanding;
1325 };
1326
1327 static void np_read_trigger(struct tevent_req *req, void *private_data);
1328 static void np_read_done(struct tevent_req *subreq);
1329
1330 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
1331                                 struct fake_file_handle *handle,
1332                                 uint8_t *data, size_t len)
1333 {
1334         struct tevent_req *req;
1335         struct np_read_state *state;
1336         NTSTATUS status;
1337
1338         req = tevent_req_create(mem_ctx, &state, struct np_read_state);
1339         if (req == NULL) {
1340                 return NULL;
1341         }
1342
1343         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
1344                 struct pipes_struct *p = talloc_get_type_abort(
1345                         handle->private_data, struct pipes_struct);
1346
1347                 state->nread = read_from_internal_pipe(
1348                         p, (char *)data, len, &state->is_data_outstanding);
1349
1350                 status = (state->nread >= 0)
1351                         ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
1352                 goto post_status;
1353         }
1354
1355         if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
1356                 struct np_proxy_state *p = talloc_get_type_abort(
1357                         handle->private_data, struct np_proxy_state);
1358
1359                 if (p->msg != NULL) {
1360                         size_t thistime;
1361
1362                         thistime = MIN(talloc_get_size(p->msg) - p->sent,
1363                                        len);
1364
1365                         memcpy(data, p->msg+p->sent, thistime);
1366                         state->nread = thistime;
1367                         p->sent += thistime;
1368
1369                         if (p->sent < talloc_get_size(p->msg)) {
1370                                 state->is_data_outstanding = true;
1371                         } else {
1372                                 state->is_data_outstanding = false;
1373                                 TALLOC_FREE(p->msg);
1374                         }
1375                         status = NT_STATUS_OK;
1376                         goto post_status;
1377                 }
1378
1379                 state->ev = ev;
1380                 state->p = p;
1381                 state->data = data;
1382                 state->len = len;
1383
1384                 if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger,
1385                                       NULL)) {
1386                         goto fail;
1387                 }
1388                 return req;
1389         }
1390
1391         status = NT_STATUS_INVALID_HANDLE;
1392  post_status:
1393         if (NT_STATUS_IS_OK(status)) {
1394                 tevent_req_done(req);
1395         } else {
1396                 tevent_req_nterror(req, status);
1397         }
1398         return tevent_req_post(req, ev);
1399  fail:
1400         TALLOC_FREE(req);
1401         return NULL;
1402 }
1403
1404 static void np_read_trigger(struct tevent_req *req, void *private_data)
1405 {
1406         struct np_read_state *state = tevent_req_data(
1407                 req, struct np_read_state);
1408         struct tevent_req *subreq;
1409
1410         subreq = read_packet_send(state, state->ev, state->p->fd,
1411                                   RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
1412         if (tevent_req_nomem(subreq, req)) {
1413                 return;
1414         }
1415         tevent_req_set_callback(subreq, np_read_done, req);
1416 }
1417
1418 static void np_read_done(struct tevent_req *subreq)
1419 {
1420         struct tevent_req *req = tevent_req_callback_data(
1421                 subreq, struct tevent_req);
1422         struct np_read_state *state = tevent_req_data(
1423                 req, struct np_read_state);
1424         ssize_t received;
1425         size_t thistime;
1426         int err;
1427
1428         received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
1429         TALLOC_FREE(subreq);
1430         if (received == -1) {
1431                 tevent_req_nterror(req, map_nt_error_from_unix(err));
1432                 return;
1433         }
1434
1435         thistime = MIN(received, state->len);
1436
1437         memcpy(state->data, state->p->msg, thistime);
1438         state->p->sent = thistime;
1439         state->nread = thistime;
1440
1441         if (state->p->sent < received) {
1442                 state->is_data_outstanding = true;
1443         } else {
1444                 TALLOC_FREE(state->p->msg);
1445                 state->is_data_outstanding = false;
1446         }
1447
1448         tevent_req_done(req);
1449         return;
1450 }
1451
1452 NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
1453                       bool *is_data_outstanding)
1454 {
1455         struct np_read_state *state = tevent_req_data(
1456                 req, struct np_read_state);
1457         NTSTATUS status;
1458
1459         if (tevent_req_is_nterror(req, &status)) {
1460                 return status;
1461         }
1462         *nread = state->nread;
1463         *is_data_outstanding = state->is_data_outstanding;
1464         return NT_STATUS_OK;
1465 }
1466
1467 /**
1468  * Create a new RPC client context which uses a local dispatch function.
1469  */
1470 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
1471                                 const struct ndr_syntax_id *abstract_syntax,
1472                                 NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
1473                                                       TALLOC_CTX *mem_ctx,
1474                                                       const struct ndr_interface_table *table,
1475                                                       uint32_t opnum, void *r),
1476                                 struct auth_serversupplied_info *serversupplied_info,
1477                                 struct rpc_pipe_client **presult)
1478 {
1479         struct rpc_pipe_client *result;
1480
1481         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
1482         if (result == NULL) {
1483                 return NT_STATUS_NO_MEMORY;
1484         }
1485
1486         result->abstract_syntax = *abstract_syntax;
1487         result->transfer_syntax = ndr_transfer_syntax;
1488         result->dispatch = dispatch;
1489
1490         result->pipes_struct = make_internal_rpc_pipe_p(
1491                 result, abstract_syntax, "", serversupplied_info);
1492         if (result->pipes_struct == NULL) {
1493                 TALLOC_FREE(result);
1494                 return NT_STATUS_NO_MEMORY;
1495         }
1496
1497         result->max_xmit_frag = -1;
1498         result->max_recv_frag = -1;
1499
1500         *presult = result;
1501         return NT_STATUS_OK;
1502 }
1503
1504 /*******************************************************************
1505  gets a domain user's groups from their already-calculated NT_USER_TOKEN
1506  ********************************************************************/
1507
1508 static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
1509                                        const DOM_SID *domain_sid,
1510                                        size_t num_sids,
1511                                        const DOM_SID *sids,
1512                                        int *numgroups,
1513                                        struct samr_RidWithAttribute **pgids)
1514 {
1515         int i;
1516
1517         *numgroups=0;
1518         *pgids = NULL;
1519
1520         for (i=0; i<num_sids; i++) {
1521                 struct samr_RidWithAttribute gid;
1522                 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
1523                         continue;
1524                 }
1525                 gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
1526                             SE_GROUP_ENABLED);
1527                 ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
1528                              gid, pgids, numgroups);
1529                 if (*pgids == NULL) {
1530                         return NT_STATUS_NO_MEMORY;
1531                 }
1532         }
1533         return NT_STATUS_OK;
1534 }
1535
1536 /****************************************************************************
1537  inits a netr_SamBaseInfo structure from an auth_serversupplied_info.
1538 *****************************************************************************/
1539
1540 static NTSTATUS serverinfo_to_SamInfo_base(TALLOC_CTX *mem_ctx,
1541                                            struct auth_serversupplied_info *server_info,
1542                                            uint8_t *pipe_session_key,
1543                                            size_t pipe_session_key_len,
1544                                            struct netr_SamBaseInfo *base)
1545 {
1546         struct samu *sampw;
1547         struct samr_RidWithAttribute *gids = NULL;
1548         const DOM_SID *user_sid = NULL;
1549         const DOM_SID *group_sid = NULL;
1550         DOM_SID domain_sid;
1551         uint32 user_rid, group_rid;
1552         NTSTATUS status;
1553
1554         int num_gids = 0;
1555         const char *my_name;
1556
1557         struct netr_UserSessionKey user_session_key;
1558         struct netr_LMSessionKey lm_session_key;
1559
1560         NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
1561         NTTIME allow_password_change, force_password_change;
1562         struct samr_RidWithAttributeArray groups;
1563         int i;
1564         struct dom_sid2 *sid = NULL;
1565
1566         ZERO_STRUCT(user_session_key);
1567         ZERO_STRUCT(lm_session_key);
1568
1569         sampw = server_info->sam_account;
1570
1571         user_sid = pdb_get_user_sid(sampw);
1572         group_sid = pdb_get_group_sid(sampw);
1573
1574         if (pipe_session_key && pipe_session_key_len != 16) {
1575                 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
1576                          "pipe_session_key_len[%zu] != 16\n",
1577                          pipe_session_key_len));
1578                 return NT_STATUS_INTERNAL_ERROR;
1579         }
1580
1581         if ((user_sid == NULL) || (group_sid == NULL)) {
1582                 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
1583                 return NT_STATUS_UNSUCCESSFUL;
1584         }
1585
1586         sid_copy(&domain_sid, user_sid);
1587         sid_split_rid(&domain_sid, &user_rid);
1588
1589         sid = sid_dup_talloc(mem_ctx, &domain_sid);
1590         if (!sid) {
1591                 return NT_STATUS_NO_MEMORY;
1592         }
1593
1594         if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
1595                 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
1596                           "%s\n but group sid %s.\n"
1597                           "The conflicting domain portions are not "
1598                           "supported for NETLOGON calls\n",
1599                           pdb_get_domain(sampw),
1600                           pdb_get_username(sampw),
1601                           sid_string_dbg(user_sid),
1602                           sid_string_dbg(group_sid)));
1603                 return NT_STATUS_UNSUCCESSFUL;
1604         }
1605
1606         if(server_info->login_server) {
1607                 my_name = server_info->login_server;
1608         } else {
1609                 my_name = global_myname();
1610         }
1611
1612         status = nt_token_to_group_list(mem_ctx, &domain_sid,
1613                                         server_info->num_sids,
1614                                         server_info->sids,
1615                                         &num_gids, &gids);
1616
1617         if (!NT_STATUS_IS_OK(status)) {
1618                 return status;
1619         }
1620
1621         if (server_info->user_session_key.length) {
1622                 memcpy(user_session_key.key,
1623                        server_info->user_session_key.data,
1624                        MIN(sizeof(user_session_key.key),
1625                            server_info->user_session_key.length));
1626                 if (pipe_session_key) {
1627                         arcfour_crypt(user_session_key.key, pipe_session_key, 16);
1628                 }
1629         }
1630         if (server_info->lm_session_key.length) {
1631                 memcpy(lm_session_key.key,
1632                        server_info->lm_session_key.data,
1633                        MIN(sizeof(lm_session_key.key),
1634                            server_info->lm_session_key.length));
1635                 if (pipe_session_key) {
1636                         arcfour_crypt(lm_session_key.key, pipe_session_key, 8);
1637                 }
1638         }
1639
1640         groups.count = num_gids;
1641         groups.rids = TALLOC_ARRAY(mem_ctx, struct samr_RidWithAttribute, groups.count);
1642         if (!groups.rids) {
1643                 return NT_STATUS_NO_MEMORY;
1644         }
1645
1646         for (i=0; i < groups.count; i++) {
1647                 groups.rids[i].rid = gids[i].rid;
1648                 groups.rids[i].attributes = gids[i].attributes;
1649         }
1650
1651         unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
1652         unix_to_nt_time(&last_logoff, get_time_t_max());
1653         unix_to_nt_time(&acct_expiry, get_time_t_max());
1654         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
1655         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
1656         unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
1657
1658         base->last_logon                = last_logon;
1659         base->last_logoff               = last_logoff;
1660         base->acct_expiry               = acct_expiry;
1661         base->last_password_change      = last_password_change;
1662         base->allow_password_change     = allow_password_change;
1663         base->force_password_change     = force_password_change;
1664         base->account_name.string       = talloc_strdup(mem_ctx, pdb_get_username(sampw));
1665         base->full_name.string          = talloc_strdup(mem_ctx, pdb_get_fullname(sampw));
1666         base->logon_script.string       = talloc_strdup(mem_ctx, pdb_get_logon_script(sampw));
1667         base->profile_path.string       = talloc_strdup(mem_ctx, pdb_get_profile_path(sampw));
1668         base->home_directory.string     = talloc_strdup(mem_ctx, pdb_get_homedir(sampw));
1669         base->home_drive.string         = talloc_strdup(mem_ctx, pdb_get_dir_drive(sampw));
1670         base->logon_count               = 0; /* ?? */
1671         base->bad_password_count        = 0; /* ?? */
1672         base->rid                       = user_rid;
1673         base->primary_gid               = group_rid;
1674         base->groups                    = groups;
1675         base->user_flags                = NETLOGON_EXTRA_SIDS;
1676         base->key                       = user_session_key;
1677         base->logon_server.string       = talloc_strdup(mem_ctx, my_name);
1678         base->domain.string             = talloc_strdup(mem_ctx, pdb_get_domain(sampw));
1679         base->domain_sid                = sid;
1680         base->LMSessKey                 = lm_session_key;
1681         base->acct_flags                = pdb_get_acct_ctrl(sampw);
1682
1683         ZERO_STRUCT(user_session_key);
1684         ZERO_STRUCT(lm_session_key);
1685
1686         return NT_STATUS_OK;
1687 }
1688
1689 /****************************************************************************
1690  inits a netr_SamInfo2 structure from an auth_serversupplied_info. sam2 must
1691  already be initialized and is used as the talloc parent for its members.
1692 *****************************************************************************/
1693
1694 NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
1695                                 uint8_t *pipe_session_key,
1696                                 size_t pipe_session_key_len,
1697                                 struct netr_SamInfo2 *sam2)
1698 {
1699         NTSTATUS status;
1700
1701         status = serverinfo_to_SamInfo_base(sam2,
1702                                             server_info,
1703                                             pipe_session_key,
1704                                             pipe_session_key_len,
1705                                             &sam2->base);
1706         if (!NT_STATUS_IS_OK(status)) {
1707                 return status;
1708         }
1709
1710         return NT_STATUS_OK;
1711 }
1712
1713 /****************************************************************************
1714  inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
1715  already be initialized and is used as the talloc parent for its members.
1716 *****************************************************************************/
1717
1718 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
1719                                 uint8_t *pipe_session_key,
1720                                 size_t pipe_session_key_len,
1721                                 struct netr_SamInfo3 *sam3)
1722 {
1723         NTSTATUS status;
1724
1725         status = serverinfo_to_SamInfo_base(sam3,
1726                                             server_info,
1727                                             pipe_session_key,
1728                                             pipe_session_key_len,
1729                                             &sam3->base);
1730         if (!NT_STATUS_IS_OK(status)) {
1731                 return status;
1732         }
1733
1734         sam3->sidcount          = 0;
1735         sam3->sids              = NULL;
1736
1737         return NT_STATUS_OK;
1738 }
1739
1740 /****************************************************************************
1741  inits a netr_SamInfo6 structure from an auth_serversupplied_info. sam6 must
1742  already be initialized and is used as the talloc parent for its members.
1743 *****************************************************************************/
1744
1745 NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
1746                                 uint8_t *pipe_session_key,
1747                                 size_t pipe_session_key_len,
1748                                 struct netr_SamInfo6 *sam6)
1749 {
1750         NTSTATUS status;
1751         struct pdb_domain_info *dominfo;
1752
1753         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1754                 DEBUG(10,("Not adding validation info level 6 "
1755                            "without ADS passdb backend\n"));
1756                 return NT_STATUS_INVALID_INFO_CLASS;
1757         }
1758
1759         dominfo = pdb_get_domain_info(sam6);
1760         if (dominfo == NULL) {
1761                 return NT_STATUS_NO_MEMORY;
1762         }
1763
1764         status = serverinfo_to_SamInfo_base(sam6,
1765                                             server_info,
1766                                             pipe_session_key,
1767                                             pipe_session_key_len,
1768                                             &sam6->base);
1769         if (!NT_STATUS_IS_OK(status)) {
1770                 return status;
1771         }
1772
1773         sam6->sidcount          = 0;
1774         sam6->sids              = NULL;
1775
1776         sam6->forest.string     = talloc_strdup(sam6, dominfo->dns_forest);
1777         if (sam6->forest.string == NULL) {
1778                 return NT_STATUS_NO_MEMORY;
1779         }
1780
1781         sam6->principle.string  = talloc_asprintf(sam6, "%s@%s",
1782                                                   pdb_get_username(server_info->sam_account),
1783                                                   dominfo->dns_domain);
1784         if (sam6->principle.string == NULL) {
1785                 return NT_STATUS_NO_MEMORY;
1786         }
1787
1788         return NT_STATUS_OK;
1789 }